Rollup setup with multiple input - rollup

I struggling with rollup setup. I want to use typescript and postcss to build following folder structure.
- Component
- ComponentA
- ComponentA.scss
- ComponentA.ts
- IconA.svg
- IconB.svg
- ComponentB
- ComponentB.scss
- ComponentB.ts
- Layout
- PageA
- PageA.scss
- PageA.ts
- PageB
- PageB.scss
- PageB.ts
- global.scss
- global.ts
I except this folder structure
- public
- Component
- ComponentA
- ComponentA.css
- ComponentA.js
- IconA.svg
- IconB.svg
- ComponentB
- ComponentB.css
- ComponentB.js
- Layout
- PageA
- PageA.css
- PageA.js
- PageB
- PageB.css
- PageB.js
- global.css
- global.js
I didn't find any related sample in docs or anywhere. I need to copy source code structure to output folder. I Wrote a simple method for discover entry points base on fs that was easy part. But how to setup outputs?

Rollup bundles your files into a single output. The structure you want is probably more suitable with something like Gulp.
However, you can still achieve what you want with Rollup. For this, you will need multiple inputs/outputs using an array as your config's default export. As an example:
export default [
{
input: 'input1.js',
output: {
file: 'outpu1.js',
format: 'cjs'
}
// ...
},
{
input: 'input2.js',
output: {
file: 'output2.js',
format: 'cjs'
}
// ...
}
// ...
];

Related

Docusaurus: How can I have multiple versions of different docs in the docs directory?

I'm working with Docusaurus to create a documentation site for 3 different education courses - all within the docs folder.
So I'm looking for a way to have the version be different across folders in there, or figure out what the best strategy for this is.
Right now, in my docusaurus.config.js I have:
module.exports = {
presets: [
'#docusaurus/preset-classic',
docs: {
lastVersion: 'current',
versions: {
current: {
label: '1.0.0',
path: '1.0.0',
},
},
},
],
};
But I'm not sure how to keep track of 3 different versions across 3 different docs all within the same site.
Swizzle the navbar via wrapping
yarn run swizzle #docusaurus/theme-classic NavbarItem/DocsVersionDropdownNavbarItem -- --wrap
Modify the swizzled component like so:
src/theme/NavbarItem/DocsVersionDropdownNavbarItem.js:
import React from "react";
import DocsVersionDropdownNavbarItem from '#theme-original/NavbarItem/DocsVersionDropdownNavbarItem';
import { useLocation } from '#docusaurus/router';
export default function DocsVersionDropdownNavbarItemWrapper(props) {
const { docsPluginId, className, type } = props
const { pathname } = useLocation()
/* (Custom) check if docsPluginId contains pathname
Given that the docsPluginId is 'charge-controller' and the routeBasePath is 'charge-controller', we can check against the current URI (pathname).
If the pathname contains the docsPluginId, we want to show the version dropdown. Otherwise, we don't want to show it.
This gives us one, global, context-aware version dropdown that works with multi-instance setups.
You want to declare a version dropdown for each plugin in your navbarItems config property for this to work well.
const doesPathnameContainDocsPluginId = pathname.includes(docsPluginId)
if (!doesPathnameContainDocsPluginId) {
return null
}
return <DocsVersionDropdownNavbarItem {...props} />;
}
For this to work, you need to have your documentation (based on products) split up using multi-instances: (https://docusaurus.io/docs/docs-multi-instance#docs-navbar-items)
Note that the preset docsPlugin ID always is "default".
You can try to use
import {
useActivePluginAndVersion,
} from '#docusaurus/plugin-content-docs/client';
const version = activePluginAndVersion.activeVersion.name; // use label instead of name if issues arise.
instead to get the current docsPluginId, name or label.
This would be the more "robust" solution I think. That said, we do use the solution I provided above as-is and it works fine for now.

elastic/search-ui - facets - filter by id but display by label

Given I have some documents in my elasticsearch index with a tag field.
{
...
tag:[
{
"id":"1",
"label":{
"en":"German",
"ger":"Deutsch"
},
{
"id":"2",
"label":{
"en":"cat",
"de":"Katze"
}
}
]
...
}
I´d like to build a frontend with elastic/search-ui and provide a facet for the tag field
so that the actual filtering is applied on basis of the id subfield.
Within the framework this can be achieved by providing a simple configuration within the configuration object.
let searchConfig: SearchDriverOptions = {
...
searchQuery:{
...
facets:{
"tag.id":{type:"value",size:"5"}
}
}
}
While this works like expected it is only half of the solution.
What I want to achieve in a next step is to display the content of tag.label.en within the ui instead of the values of tag.id.
In the end the filtering should be done on basis of tag.id but in the UI the corresponding value of tag.label.en should be shown.
Is there a simple way to achieve this in elastic/search-ui?

Vuex state structure and fetching when using same type of data with different values on different routes

I'm creating a portfolio with vue, vuex and vue-router that will show images.
On the homepage i will show images with 'show_home: true'.
Then there is "tag" pages (portfolio/:tagSlug) that will show images based on a slug, eg. 'weddings' with infinite scroll (auto populate pagination).
An image object will look something like:
{
id: 1,
title: 'Lorem..',
path: '..',
show_home: true
tags: [ {id: 1, slug: 'weddings'} ]
},
{
id: 2,
title: 'Lorem2..',
path: '..',
show_home: false
tags: [ {id: 1, slug: 'weddings'}, {id: 2, slug: 'water'} ]
}
Endpoints examples:
Homepage: GET: ../images/homepage?p=1
Tag page: GET: ../images/:slug?p=1
I can't figure out how I should structure this in vuex and handle the fetching..
Should i just create i single 'images: []' state and populate it with ALL the images after fetching them from the api in each route, then filter them with getters? How can i get the pagination in there in that case? Or do you have a better solution?
Thanks in advance
My preferred approach is to "flatten" the relationships and pull them as needed. This also allows you to only pull what you need from the server or related modules.
tags vuex module:
all: {
1: { <-- indexed by tag id
name: "weddings"
images: [1,2,3,4] <-- image ids
}
}
active: false <-- When there is an active tag, this becomes the id of the tag.
The vuex images module would follow this same pattern:
all: {
1: { <-- indexed by image id
title: 'Lorem..',
path: '..',
show_home: true
tags: [1,2,3,4] <-- tag ids
}
}
active: false <-- When there is an active image, this becomes the id of the image.
Then use a getter to hydrate the images or tags from the respective vuex module.
There is a great write up on this approach on this blog: https://medium.com/js-dojo/structuring-vuex-modules-for-relationships-speed-and-durability-de25f7403643
With this approach you will have fewer and smaller api calls, pagination is manageable and you don't need to worry about stale data in your relationships.
EDITED -- API info:
Two approaches come to mind.
1) always load the images with the tag.
Tag index request would not load any images, just the basic info for each tag.
When the user clicks on a tag, this inits an API call for the tag details:
Tag show request (tags/1 or tags/weddings) would return the tag with loaded relationships:
public function show($id)
{
$tag = Tag::where('id', $id)->with('images')->firstOrFail();
return new TagResource($tag); <-- will have all related images loaded.
}
2) set up a nested REST endpoint if needed
You can use the the resource controllers to shortcut the boilerplate like this:
api.php
Route::apiResource('tags.images', 'tags\TagImageController');
This route will watch your api calls and determine if it is index/store/show/delete. From your front end you can make a call like https://backendsite.com/tags/1/images (If wedding tag has an id of 1)
Then in the TagImageController you would have something like this:
public function index(Request $request, $id)
{
$tag = MemTag::find($id);
$images = $tag->images()->get();
$images->load(Image::allowedIncludes); <- or you can manually list relationships you want to load
return ImageResource::collection($images);
}

Vue-CLI build number - does it exist and how could it be used in a Vue app itself?

I have a Vue app being built for production deployment using Vue CLI.
I would like to include a typical incrementing build number in the application, so that I and testers can be sure we are testing the correct exact build. I would like to use it in the application in at least two ways a) to display it to a tester, and b) to included it in bug-tracking API calls e.g. to Sentry.io.
Currently I have to look at the hash on the app.XXXX.js and compare that. While this does uniquely identify the build, it's not sequential, is different for the CSS/JS/vendors etc and would be difficult to use in the codebase.
I'm happy to write a build wrapper script which manages the number and injects it into the build if that's what it takes.
The command I'm currently using is e.g.
npx vue-cli-service build --mode staging
I've implemented something using the date and time. It's in a Vue 2 project.
Add this code (or something like it) to the top of the vue.config.js file:
const verMajor = 1;
const verMinor = 0;
const now = new Date();
const padTwo = (val) => (val > 9 ? "" : "0") + val;
const nowMonth = now.getMonth() + 1;
const nowDay = now.getDate();
const verBuildDate = now.getFullYear() + padTwo(nowMonth) + padTwo(nowDay);
const verBuildTime = padTwo(now.getHours()) + padTwo(now.getMinutes()) + padTwo(now.getSeconds());
process.env.VUE_APP_VERSION = `${verMajor}.${verMinor}.${verBuildDate}.${verBuildTime}`;
console.log(`Building version: ${process.env.VUE_APP_VERSION}`);
// ...rest of the config
In the component code, you can do this:
get versionText(): string {
return process.env.VUE_APP_VERSION;
}
But I'm using class-based components so if you're not, I guess this will work instead:
computed: {
versionText: funnction () {
return process.env.VUE_APP_VERSION;
}
}
And in the template:
Ver: {{versionText}}
This results in something like:
Ver: 1.0.20211013.110634
If that looks too long, I'm sure it could be shortened according to your needs - or you could store a number in a file and write some JS in the config file to increment it on each build - or each release build if you check process.env.NODE_ENV === "release".
For further information, see: https://cli.vuejs.org/guide/mode-and-env.html
:o)

How to import a directory into a single file component

I am using a photo gallery component in my project. It requires a path to the folder containing the images. I am unable to find a way to do this. I have created an img directory inside of assets, and I'm using the standard Vue CLI 3 scaffolding. I'm able to use a require('path/to/file/name.png'), but what I need is to be able to bring the whole folder in. I'm unable to figure out a way to do this. I even tried placing the images in a folder inside of public, but no luck.
My structure looks like this:
project/public/img
project/src/assets/img/
project/src/components/
I need to get the project/src/assets/img path into a component inside of project/src/components/componentName.vue.
I should also mention that I want to be able to access this directory from the script tag, not the template tag.
You can try something like this:
const requireModule = require.context('../assets/img.',false,/\.png$/)
const images = {}
requireModule.keys().forEach(filename =>
{
const imageName = fileName.replace(/(\.\/|\.png)/g, '');
images[imageName] = requireModule(fileName)
OR
images[imageName] =
{
namespaced: true,
...requireModule(fileName)
}
});
export default images;
Then you can import this file
import photos from 'imagesObject.js'
for (let key in photos) // do whatever you want with the image
Thank you for your answer IVO. That solution did work, but I found another that I wanted to share here for anyone else having a similar problem. The issue I was having was incorrectly referencing the public folder using a relative path instead of BASE_URL. Based on this...
The public Folder Vue CLI Documentation
I created a directory inside of /public then referenced it using process.env.BASE_URL. This solved the problem. Here are the relevant snippets:
Javascript:
data () {
return {
thumbnailDir : process.env.BASE_URL + 'portfolio/'
}
Template:
<transition-group name="thumbnailfade" tag="div">
<img v-for="thumb in filteredImages"
:key="thumb.id"
#click="showLightbox(thumb.name)"
:src="thumbnailDir + thumb.name"
:alt="thumb.alt"
:title="thumb.alt"/>
</transition-group>
<lightbox id="mylightbox"
ref="lightbox"
:images="images"
:directory="thumbnailDir"
:filter="galleryFilter"
:timeoutDuration="5000"
/>