Configure Rollup (under Vite) build to create separate bundles with theirs assets - javascript

Need your help )
I'm stuck with question - how to configure Rollup build to achieve next build structure.
For example - let's assume that folder structure (it's possible to change it) is:
├── src/
│ ├── common-assets/
│ │ └── ...
│ └-- sections/
│ ├── first-section/
│ │ ├── first-app/
│ │ │ ├── app/
│ │ │ │ ├── app-assets/
│ │ │ │ │ └── ...
│ │ │ │ ├── app-components/
│ │ │ │ │ └── ...
│ │ │ │ └-- ...
│ │ │ ├── app.ts
│ │ │ └── index.html
│ │ ├── second-app/
│ │ │ ├── app/
│ │ │ └── ...
│ │ │ ├── app.ts
│ │ │ └── index.html
│ │ └-- ...
│ ├── second-section/
│ │ ├── first-app/
│ │ │ ├── app/
│ │ │ └── ...
│ │ │ ├── app.ts
│ │ │ ├── index.html
│ │ ├── second-app/
│ │ │ ├── app/
│ │ │ └── ...
│ │ │ ├── app.ts
│ │ │ └── index.html
│ │ └-- ...
│ └-- ...
├── index.html
├── main.ts
├── package.json
└── vite.config.ts
Folder sections consists of group folders. Each group folder (first-section, second-section, ...) groups apps of particular kind.
That's what I need to get after build done inside dist directory:
├── first-section/
│ ├── first-app/
│ │ ├── app-assets/
│ │ │ └── ...
│ │ ├── common-assets/
│ │ │ └── ...
│ │ ├── bundle.js
│ │ └── index.html
│ ├── second-app/
│ │ ├── app-assets/
│ │ │ └── ...
│ │ ├── common-assets/
│ │ │ └── ...
│ │ ├── bundle.js
│ │ └── index.html
│ └-- ...
├── second-section/
│ ├── first-app/
│ │ ├── app-assets/
│ │ │ └── ...
│ │ ├── common-assets/
│ │ │ └── ...
│ │ ├── bundle.js
│ │ └── index.html
│ ├── second-app/
│ │ ├── app-assets/
│ │ │ └── ...
│ │ ├── common-assets/
│ │ │ └── ...
│ │ ├── bundle.js
│ │ └── index.html
│ └-- ...
└-- ...
So, each *-section directory should includes common-assets and it's own index.html + bundle.js files.
Each app (first-app, second-app, ...) will be used and served as separate application (with it's own store/routing/etc).

I am struggling as well to do this with vite. I think vite is not intended for this usecase. There is a workaround I did, that maybe you can adapt to your purposes.
Basically, I have two html files I want to fill: app1.html and app2.html.
Each app's source code is in its own directory: src/app1 and src/app2.
The apps share very few resources, but I still want to build those two in one go.
My structure is as follows:
├── app1.html
├── app2.html
├── src
│ ├── app1
│ │ ├── App.svelte
│ │ ├── components
│ │ │ └── Component.svelte
│ │ └── main.ts
│ ├── app2
│ │ ├── App.svelte
│ │ ├── components
│ │ │ └── Component.svelte
│ │ └── main.ts
│ ├── shared
│ │ ├── global.css
│ │ └── shared.ts
│ └── vite-env.d.ts
├── svelte.config.js
├── tsconfig.json
├── tsconfig.node.json
└── vite.config.ts
You can see there are two separate apps: src/app1 and src/app2 with similar structure.
I could not find a way to build them separately using only one call to defineConfig, so basically I build the apps separately, using the emptyOutDir: false. This way I won't lose one build when doing the other.
Then, I created some scripts in my package.json:
"scripts": {
"build": "vite build",
"build:app1": "vite build",
"build:app2": "vite build",
"build:all": "pnpm build:app1 && pnpm build:app2",
...
},
The good part about this, is that from vite.config.ts i can access the name of the command using process.env.npm_lifecycle_event. It will be set to build:app1 if I do pnpm build:app1. I can use this to choose which part of the source code to build.
This is my vite.config.ts:
import { defineConfig } from "vite";
import { svelte } from "#sveltejs/vite-plugin-svelte";
const buildScript = process.env.npm_lifecycle_event;
const app = buildScript.includes(":") ? buildScript.split(":")[1] : "app1";
const buildConfig = {
rootHtml: `./${app}.html`,
entryFileNames: `${app}/${app}.js`,
assetFileNames: `${app}/${app}.[ext]`,
};
export default defineConfig({
plugins: [svelte()],
build: {
rollupOptions: {
input: { app: buildConfig.rootHtml },
output: {
entryFileNames: buildConfig.entryFileNames,
assetFileNames: buildConfig.assetFileNames,
},
},
emptyOutDir: false,
},
server: { open: buildConfig.rootHtml },
});
After running pnpm build:all, the dist folder should look like this:
dist
├── app1
│ ├── app1.js
│ └── app1.css
├── app1.html
├── app2
│ ├── app2.js
│ └── app2.css
└── app2.html
I hope this helps. I may try to use rollup instead of vite to see if I can do it more elegantly, but this workaround helped me achieve my goal.

Related

Node & Typescript; Atomizing IMPORT/EXPORT

Good day!
I'm Working on a personnel projet. A backend using node and typescript.
I've been looking at some architectures and I choose my data layer to be a factory pattern reflecting table operation. In a class, I can wrap up most queries in fonction using 10-20 line per operations. But I'm not sure if I will go with the same pattern for the business layer
Data
├── connections
│ └── mysql.ts
├── models
│ └── user.model.ts
│ └── product.model.ts
└── tables
└── user.table.ts
└── product.table.ts
└── order.table.ts
Because I dont validate parameters(done in business layer) this pattern works fine because query functions or kept fairly small. Functions only return's a result or null. Then Business layer will determine the proper error message(not found, login failed, product is back order....etc)
Now, because business layer require more logics. Thus more lines of code for parameters validation, permissions, data queries, other API calls, error handling ... etc. I strongly think I should use the modules mechanism. Wrapping up a single method in a file. Then only import the business function to an entry point.
Business
├── procedures
│ ├── authentication
│ │ ├── connections.ts
│ │ ├── delete.ts
│ │ ├── login.ts
│ │ ├── logout.ts
│ │ ├── signup.ts
│ │ └── suspend.ts
│ ├── product
│ │ ├── create.ts
│ │ ├── delete.ts
│ │ ├── find.ts
│ │ ├── read.ts
│ │ ├── reserve.ts
│ │ ├── update_description.ts
│ │ ├── update_price.ts
│ │ └── update.ts
│ └── user
│ ├── create.ts
│ ├── delete.ts
│ ├── find.ts
│ ├── read.ts
│ └── update.ts
└── validations
├── authentication
│ ├── connections.ts
│ ├── delete.ts
│ ├── login.ts
│ ├── logout.ts
│ ├── signup.ts
│ └── suspend.ts
├── product
│ ├── create.ts
│ ├── delete.ts
│ ├── find.ts
│ ├── read.ts
│ ├── reserve.ts
│ ├── update_description.ts
│ ├── update_price.ts
│ └── update.ts
└── user
├── create.ts
├── delete.ts
├── find.ts
├── read.ts
└── update.ts
Business layer will be consume by Express routes(no details need it here).
I segmented my validations to reflect the same structure as the procedures directory because AJV validation schema can get pretty big.
I anticipate about 20 Business object with an average of 7 fonctions each. Times 2 for validation. For a total average of 240 files for the business layer.
So, my questions is. Is atomizing business function using import/export in a single file per business function a good practice and will it diminish performance?
RTFMed lots of howto's on import/export but cant seem to find straight answer or performance concern.

Character * in dynamic import

Good morning everyone, I have a project with the following structure:
intranet
├── modulos
│ ├── almacen
│ │ ├── views
│ │ └── route
│ │ └── index.js
│ │
│ ├── ventas
│ │ ├── views
│ │ └── route
│ │ └── index.js
│ │
│ └── compras
│ ├── views
│ ├── route
│ └── index.js
│
├── route
│ └── index.js
├── store
│ └── index.js
├── ...
The modules folder will have all the modules that I will be connecting to the project, the point is that all the subfolders will have the views, route, etc. subfolders. In turn, in the route folder there will always be an index.js file.
Now in the intranet > route > index file I want to do the import as follows.
import("../modulos/*/route/index").then(module => {
console.log(module);
});
This in order to carry out a self-import of those modules that it finds. The problem is that I get an error because apparently the character * (asterisk) is not allowed inside the import.
I will appreciate the help you give me. Thank you.
This is not possible you have to iterate over all directories in 'modulos'
// pseudo code
for(const folder in modulos_subfolders) {
import(``../modulos/${folder}/route/index`)
}

Docker and Node js Error: Cannot find module

What am I dong wrong here?
The code works on my computer, but when I run it in docker it fails.
I get the following error:
Error: Cannot find module
'/usr/src/app/src/Presentation/viewModel/index'
at Function.Module._resolveFilename (module.js:538:15)
at Function.Module._load (module.js:468:25)
at Module.require (module.js:587:17)
at require (internal/module.js:11:18)
at /usr/src/app/app.js:29:18
at Array.forEach ()
at Object. (/usr/src/app/app.js:28:26)
at Module._compile (module.js:643:30)
at Object.Module._extensions..js (module.js:654:10)
at Module.load (module.js:556:32) npm ERR! code ELIFECYCLE npm ERR! errno 1
I assume that the issue is not in docker since when I play with the require I can get different errors.
Just in case here is the docker file:
FROM node:8.9-alpine
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD npm start
Here is my app.js file which loads the module which failed:
// Load routes and load dependices - Views and ViewModel
routesConfig.getRoutes().forEach(function(route){
var routeTmp = require(path.join(__dirname,'src/Presentation/viewModel/'+route[1]));
app.use(route[0], routeTmp);
});
It failed at the require line....
When I play with the required files I get different errors, I assume that the module.export makes the problem but I don't know how to go deeper in debugging.
var express = require('express');
var router = express.Router();
var serviceConfig = require('../../../config/service');
var navigation = require('../view/navigation/navigation');
// TODO
var Base = require('../../Core/Common/Base');
const base = new Base();
// Create service
const classTmp = base.getService().create(serviceConfig.getServices().baseService);
var user = classTmp.getAdmin();
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', {
title: 'Expasdress',
fields: navigation.getNavigation(),
user: user
}
);
});
module.exports = router;
Here is the project sturcture:
.
├── Dockerfile
├── Jenkinsfile
├── app.js
├── bin
│ └── www
├── config
│ ├── config.js
│ ├── createConfig.js
│ ├── domains.js
│ ├── routes.js
│ └── service.js
├── dive.log
├── k8s
│ ├── ingress
│ │ └── ingress.yaml
│ ├── pod
│ │ └── pod.yaml
│ ├── production
│ │ └── production.yaml
│ ├── rbac
│ │ └── fabric8-rbac.yaml
│ └── services
│ └── backend.yaml
├── package-lock.json
├── package.json
├── public
│ ├── icons
│ │ ├── add-thumbnail-placeholder.svg
│ │ ├── baseline-change_history-24px.svg
│ │ └── spartan-logo.png
│ ├── script
│ │ ├── app-view.js
│ │ ├── create-package.js
│ │ ├── sidebar.js
│ │ └── tag-input.js
│ └── stylesheets
│ ├── admin-base.css
│ ├── app.css
│ ├── base.css
│ ├── bootstrap
│ │ ├── css
│ │ │ ├── bootstrap-theme.css
│ │ │ └── bootstrap.css
│ │ ├── fonts
│ │ │ ├── glyphicons-halflings-regular.eot
│ │ │ ├── glyphicons-halflings-regular.svg
│ │ │ ├── glyphicons-halflings-regular.ttf
│ │ │ ├── glyphicons-halflings-regular.woff
│ │ │ └── glyphicons-halflings-regular.woff2
│ │ └── js
│ │ ├── bootstrap.js
│ │ ├── bootstrap.min.js
│ │ └── npm.js
│ ├── component
│ │ ├── buttons.css
│ │ ├── create-components.css
│ │ ├── create-content.css
│ │ └── tag-input.css
│ ├── create-package.css
│ ├── login.css
│ ├── main.css
│ ├── material.css
│ ├── packages.css
│ ├── sidebar.css
│ ├── standard-list.css
│ ├── statistics.css
│ └── style.css
├── scratch
│ ├── access_token
│ ├── email
│ ├── image
│ ├── name
│ ├── refresh_token
│ ├── scope
│ ├── surname
│ └── userToken
└── src
├── Core
│ ├── Abstract
│ │ ├── Domain.js
│ │ └── Service.js
│ ├── Common
│ │ └── Base.js
│ ├── Database
│ │ └── SQLiteDatabase.js
│ ├── Factory
│ │ ├── DomainFactory.js
│ │ └── ServiceFactory.js
│ ├── Observer
│ │ └── EventObserver.js
│ └── RequestHandler
│ └── RequestHandler.js
├── Models
│ ├── Domain
│ │ ├── Component
│ │ │ └── NameComponentDomain.js
│ │ ├── Create
│ │ │ ├── CreateDomain.js
│ │ │ ├── DeleteDomain.js
│ │ │ ├── EditDomain.js
│ │ │ └── ReleaseDomain.js
│ │ ├── List
│ │ │ └── ListDomain.js
│ │ ├── Login
│ │ │ └── LoginDomain.js
│ │ ├── Search
│ │ │ └── SearchDomain.js
│ │ └── Statistics
│ │ └── StatisticsDomain.js
│ ├── Entity
│ │ ├── Admin.js
│ │ ├── Plan.js
│ │ └── Request.js
│ ├── Mapper
│ ├── Repository
│ │ └── StorageRepository.js
│ └── Service
│ ├── BaseService.js
│ ├── CreateService.js
│ └── GetService.js
└── presentation
├── ObjectMapper
├── view
│ ├── app.pug
│ ├── appsku.pug
│ ├── component
│ │ ├── addEquipmentTags.pug
│ │ ├── addTags.pug
│ │ ├── description.pug
│ │ ├── imageLoader.pug
│ │ ├── name.pug
│ │ ├── plan-cell.pug
│ │ └── title.pug
│ ├── create-package.pug
│ ├── create.pug
│ ├── error.pug
│ ├── exercise.pug
│ ├── index.pug
│ ├── login.pug
│ ├── main
│ │ ├── baseLogin.pug
│ │ └── baseNonLoged.pug
│ ├── navigation
│ │ └── navigation.js
│ ├── nutrition-plan.pug
│ ├── package.pug
│ ├── statistics.pug
│ ├── tag.pug
│ ├── workout-plan.pug
│ └── workout.pug
└── viewModel
├── Component
│ └── Name.js
├── app.js
├── appsku.js
├── create-app.js
├── create-package.js
├── exercise.js
├── index.js
├── login.js
├── nutrition-plan.js
├── package.js
├── statistics.js
├── tag.js
├── workout-plan.js
└── workout.js
I will be desperate enough to put my git code as well:https://github.com/tech-387/spartan-apps-admin-console-frontend

Heroku deployment from travis for Meteor App

I'm trying to deploy to Heroku my out of the box meteor application using Travis-CI. Everything goes perfect, no error in the logs, so I try to go to my app link but I get this message:
Application error
___________________________________________________________________________________________________________
An error occurred in the application and your page could not be served. Please try again in a few moments.
If you are the application owner, check your logs for details.
Here is the .travis.yml file
sudo: required
language: node_js
node_js:
- "stable"
deploy:
provider: heroku
api_key:
secure: "mysecretapikey"
app:
master: agile
And here the log generated from heroku
-----> Node.js app detected
-----> Creating runtime environment
NPM_CONFIG_LOGLEVEL=error
NPM_CONFIG_PRODUCTION=true
NODE_ENV=production
NODE_MODULES_CACHE=true
-----> Installing binaries
engines.node (package.json): unspecified
engines.npm (package.json): unspecified (use default)
Resolving node version (latest stable) via semver.io...
Downloading and installing node 5.11.1...
Using default npm version: 3.8.6
-----> Restoring cache
Skipping cache restore (new runtime signature)
-----> Building dependencies
Pruning any extraneous modules
Installing node modules (package.json)
agile# /tmp/build_ea656fe1ea6609f45441b9fe1ead456609
└─┬ meteor-node-stubs#0.2.3
├── assert#1.3.0
├─┬ browserify-zlib#0.1.4
│ └── pako#0.2.8
├─┬ buffer#4.5.1
│ ├── base64-js#1.1.2
│ ├── ieee754#1.1.6
│ └── isarray#1.0.0
├─┬ console-browserify#1.1.0
│ └── date-now#0.1.4
├── constants-browserify#1.0.0
├─┬ crypto-browserify#3.11.0
│ ├─┬ browserify-cipher#1.0.0
│ │ ├─┬ browserify-aes#1.0.6
│ │ │ ├── buffer-xor#1.0.3
│ │ │ └── cipher-base#1.0.2
│ │ ├─┬ browserify-des#1.0.0
│ │ │ ├── cipher-base#1.0.2
│ │ │ └─┬ des.js#1.0.0
│ │ │ └── minimalistic-assert#1.0.0
│ │ └── evp_bytestokey#1.0.0
│ ├─┬ browserify-sign#4.0.0
│ │ ├── bn.js#4.11.1
│ │ ├── browserify-rsa#4.0.1
│ │ ├─┬ elliptic#6.2.3
│ │ │ ├── brorand#1.0.5
│ │ │ └── hash.js#1.0.3
│ │ └─┬ parse-asn1#5.0.0
│ │ ├─┬ asn1.js#4.5.2
│ │ │ └── minimalistic-assert#1.0.0
│ │ ├─┬ browserify-aes#1.0.6
│ │ │ ├── buffer-xor#1.0.3
│ │ │ └── cipher-base#1.0.2
│ │ └── evp_bytestokey#1.0.0
│ ├─┬ create-ecdh#4.0.0
│ │ ├── bn.js#4.11.1
│ │ └─┬ elliptic#6.2.3
│ │ ├── brorand#1.0.5
│ │ └── hash.js#1.0.3
│ ├─┬ create-hash#1.1.2
│ │ ├── cipher-base#1.0.2
│ │ ├── ripemd160#1.0.1
│ │ └── sha.js#2.4.5
│ ├── create-hmac#1.1.4
│ ├─┬ diffie-hellman#5.0.2
│ │ ├── bn.js#4.11.1
│ │ └─┬ miller-rabin#4.0.0
│ │ └── brorand#1.0.5
│ ├── inherits#2.0.1
│ ├── pbkdf2#3.0.4
│ ├─┬ public-encrypt#4.0.0
│ │ ├── bn.js#4.11.1
│ │ ├── browserify-rsa#4.0.1
│ │ └─┬ parse-asn1#5.0.0
│ │ ├─┬ asn1.js#4.5.2
│ │ │ └── minimalistic-assert#1.0.0
│ │ ├─┬ browserify-aes#1.0.6
│ │ │ ├── buffer-xor#1.0.3
│ │ │ └── cipher-base#1.0.2
│ │ └── evp_bytestokey#1.0.0
│ └── randombytes#2.0.3
├── domain-browser#1.1.7
├── events#1.1.0
├─┬ http-browserify#1.7.0
│ ├── Base64#0.2.1
│ └── inherits#2.0.1
├── https-browserify#0.0.1
├── os-browserify#0.2.1
├── path-browserify#0.0.0
├── process#0.11.2
├── punycode#1.4.1
├── querystring-es3#0.2.1
├─┬ readable-stream#2.0.6
│ ├── core-util-is#1.0.2
│ ├── inherits#2.0.1
│ ├── isarray#1.0.0
│ ├── process-nextick-args#1.0.6
│ └── util-deprecate#1.0.2
├─┬ stream-browserify#2.0.1
│ └── inherits#2.0.1
├── string_decoder#0.10.31
├── timers-browserify#1.4.2
├── tty-browserify#0.0.0
├─┬ url#0.11.0
│ ├── punycode#1.3.2
│ └── querystring#0.2.0
├─┬ util#0.10.3
│ └── inherits#2.0.1
└─┬ vm-browserify#0.0.4
└── indexof#0.0.1
-----> Caching build
Clearing previous node cache
Saving 2 cacheDirectories (default):
- node_modules
- bower_components (nothing to cache)
-----> Build succeeded!
└── meteor-node-stubs#0.2.3
-----> Discovering process types
Procfile declares types -> (none)
Default types for buildpack -> web
-----> Compressing...
Done: 13.1M
-----> Launching...
Released v3
As said before, it's an out-of-the-box app so there is no database, nothing that could be causing permission troubles on the server.
I found my mistake, I needed to use buildpack with one of the availables for meteor in order for the app to start. I went to the command line and run heroic logs and saw the errors. I add my new .travis.yml file just in case someone steps into the same error as me:
sudo: required
language: node_js
node_js:
- "stable"
deploy:
provider: heroku
buildpack: https://github.com/jordansissel/heroku-buildpack-meteor.git
api_key:
secure: "mysecretapikey"
app:
master: agile

Issue installing Handlebars.js with npm

I am having an issue installing handlebars with Node npm, and in general understanding how to use require() in general.
It appears that the Handlebars module is not installed at all.
Within WebStorm terminal I installed the following successfully:
npm install handlebars
npm install require
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Todo App: Vanilla JS, Bootstrap, Handlebars</title>
</head>
<body>
<ul class="shoesNav">
<script id="body-template" type="x-handlebars-template">
{{#each this}}
<li class="shoes">{{name}} -- Price: {{price}}</li>
{{/each}}
</script>
</ul>
<script type="text/javascript">
var Handlebars = require('handlebars');
var shoesData = [{name:"Nike", price:199.00 }, {name:"Loafers", price:59.00 }, {name:"Wing Tip", price:259.00 }];
//Get the HTML from the template in the script tag​
var theTemplateScript = document.getElementById("body-template").innerHTML;
alert(theTemplateScript);
//Compile the template​
var theTemplate = Handlebars.compile(theTemplateScript);
document.getElementsByClassName("shoesNav")[0].appendChild(theTemplate);
//We pass the shoesData object to the compiled handleBars function​
// The function will insert all the values from the objects in their respective places in the HTML and returned HTML as a string. Then we use jQuery to append the resulting HTML string into the page​
</script>
</body>
</html>
├─┬ handlebars#4.0.5
│ ├── async#1.5.0
│ ├─┬ optimist#0.6.1
│ │ ├── minimist#0.0.10
│ │ └── wordwrap#0.0.3
│ ├─┬ source-map#0.4.4
│ │ └── amdefine#1.0.0
│ └─┬ uglify-js#2.6.1
│ ├── async#0.2.10
│ ├── source-map#0.5.3
│ ├── uglify-to-browserify#1.0.2
│ └─┬ yargs#3.10.0
│ ├── camelcase#1.2.1
│ ├─┬ cliui#2.1.0
│ │ ├─┬ center-align#0.1.2
│ │ │ ├─┬ align-text#0.1.3
│ │ │ │ ├─┬ kind-of#2.0.1
│ │ │ │ │ └── is-buffer#1.1.0
│ │ │ │ ├── longest#1.0.1
│ │ │ │ └── repeat-string#1.5.2
│ │ │ └── lazy-cache#0.2.7
│ │ ├─┬ right-align#0.1.3
│ │ │ └─┬ align-text#0.1.3
│ │ │ ├─┬ kind-of#2.0.1
│ │ │ │ └── is-buffer#1.1.0
│ │ │ ├── longest#1.0.1
│ │ │ └── repeat-string#1.5.2
│ │ └── wordwrap#0.0.2
│ ├── decamelize#1.1.1
│ └── window-size#0.1.0
└─┬ require#2.4.20
├── std#0.1.40
└─┬ uglify-js#2.3.0
├── async#0.2.10
├─┬ optimist#0.3.7
│ └── wordwrap#0.0.3
└─┬ source-map#0.1.43
└── amdefine#1.0.0
AMD syntax (like require) is not supported by browsers.
You have installed modules designed to run within Node.JS, not embedded in an HTML document and served up to a browser.
Tools like webpack and browserify let you use AMD modules in a browser (providing they don't depend on features not supported by browsers).
Alternatively, you could get a version of handlebars designed for use in a browser by following the install instructions for a bower or manual install.

Categories

Resources