Webpack config + set multiple public path values - node.js

I have two different modules like students and staff.
For students files should be created into the dist folder with static path /students' - publicPath: "/students/".
For staff files should be created into dist folder without static path(root folder).
I set the publicPath: "/students/" but staff files static path also included with students.
I have added the config below
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
module.exports = {
entry: {
students: [
'./students/css/students.css',
'./students/js/students.js',
'./students/templates/students/index.pug'
],
staff: [
'./staff/css/index.css',
'./staff/js/index.js',
'./staff/templates/index.pug',
]
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].js',
publicPath: "/students/"
},
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html',
template: './students/templates/students/index.pug',
chunks: ['students'],
}),
new HtmlWebpackPlugin({
filename: 'staff.html',
template: './staff/templates/index.pug',
chunks: ['staff'],
})
]
};

You can use Exporting multiple configurations. Create multiple WebPack configurations to build different modules. So that you specify publicPath for each config.
Folder structure:
⚡ tree -L 4 -I 'node_modules'
.
├── dist
│ ├── staff.css
│ ├── staff.html
│ ├── staff.js
│ ├── student.html
│ ├── students.css
│ └── students.js
├── package-lock.json
├── package.json
├── staff
│ ├── css
│ │ └── index.css
│ ├── js
│ │ └── index.js
│ └── templates
│ └── index.html
├── students
│ ├── css
│ │ └── index.css
│ ├── js
│ │ └── index.js
│ └── templates
│ └── index.html
└── webpack.config.js
9 directories, 15 files
E.g.
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const path = require("path");
module.exports = [
{
mode: "development",
entry: {
students: "./students/js/index.js",
},
output: {
path: path.resolve(__dirname, "dist"),
filename: "[name].js",
publicPath: "/students/",
},
module: {
rules: [
{
test: /\.css$/i,
use: [MiniCssExtractPlugin.loader, "css-loader"],
},
],
},
plugins: [
new HtmlWebpackPlugin({
filename: "student.html",
template: "./students/templates/index.html",
chunks: ["students"],
}),
new MiniCssExtractPlugin(),
],
},
{
mode: "development",
entry: {
staff: "./staff/js/index.js",
},
output: {
path: path.resolve(__dirname, "dist"),
filename: "[name].js",
publicPath: "/",
},
module: {
rules: [
{
test: /\.css$/i,
use: [MiniCssExtractPlugin.loader, "css-loader"],
},
],
},
plugins: [
new HtmlWebpackPlugin({
filename: "staff.html",
template: "./staff/templates/index.html",
chunks: ["staff"],
}),
new MiniCssExtractPlugin(),
],
},
];
Output:
dist/staff.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script defer src="/staff.js"></script><link href="/staff.css" rel="stylesheet"></head>
<body>
</body>
</html>
dist/students.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script defer src="/students/students.js"></script><link href="/students/students.css" rel="stylesheet"></head>
<body>
</body>
</html>

Related

How do I change the input dir in ViteJS?

I'm trying to build/compile a demo page for my plugin with ViteJS. How do I pinpoint ViteJS to my file that needs to be compiled?
my-plugin/
├─ demo/
│ ├─ resources/js/
│ │ ├─ app.js <---- This needs to be read (`npm run build:demo`)
│ ├─ public/js/
│ │ ├─ app.js <---- This should be my ViteJS demo output (outDir)
├─ node_modules/
├─ dist/ <---- This works ✅ (`npm run build:dist`)
│ ├─ index.mjs
│ ├─ index.umd.js
├─ src/
│ ├─ index.js
├─ index.html <---- This is the demo index.html that is needed for GitHub (cannot change the location)
├─ package.json
I have added these lines of code in
// package.json
...
"scripts": {
"build:dist": "LIB_NAME=dist vite build",
"build:demo": "LIB_NAME=demo vite build",
"build": "npm run build:dist && npm run build:demo",
},
...
I want to run npm run build:demo. But I get errors, like:
[vite]: Rollup failed to resolve import "/demo/public/js/app.js" from "index.html".
This is most likely unintended because it can break your application at runtime...
My vite.config.js looks like this:
import { defineConfig } from 'vite';
import vue from '#vitejs/plugin-vue';
import cssInjectedByJsPlugin from 'vite-plugin-css-injected-by-js';
const path = require('path');
const config = {
dist: {
build: {
lib: {
entry: path.resolve(__dirname, './src/index.js'),
name: 'VueResponsiveVideoBackgroundPlayer',
fileName: 'vue-responsive-video-background-player',
},
rollupOptions: {
external: ['vue'],
output: {
// Provide global variables to use in the UMD build
// Add external deps here
globals: {
vue: 'Vue',
},
exports: 'named',
},
},
outDir: './dist',
},
plugins: [
vue(),
cssInjectedByJsPlugin(),
],
},
demo: {
// <--------- This is the part where I have to change something
// root: './demo/resources/js/',
build: {
outDir: './demo/public/js',
},
plugins: [
vue(),
cssInjectedByJsPlugin(),
],
},
};
const currentConfig = config[process.env.LIB_NAME];
if (currentConfig === undefined) {
throw new Error('LIB_NAME is not defined or is not valid');
}
// https://vitejs.dev/config/
export default defineConfig({
...currentConfig,
plugins: [
vue(),
cssInjectedByJsPlugin(),
],
});
It would be awesome, if I could somehow say to ViteJS please use ./demo/resources/js/app.js as the input and after the compile set the output to ./demo/public/js.app.js.
Here is the source if you need it.
Yeah I found the solution:
It took me a while, but have look at my vite.config.js file.
// https://www.raulmelo.dev/blog/build-javascript-library-with-multiple-entry-points-using-vite-3
import { defineConfig } from 'vite';
import vue from '#vitejs/plugin-vue';
import cssInjectedByJsPlugin from 'vite-plugin-css-injected-by-js';
const path = require('path');
const config = {
// npm run build:dist for npm
dist: {
build: {
outDir: './dist',
lib: {
entry: path.resolve(__dirname, './src/index.js'),
name: 'VueResponsiveVideoBackgroundPlayer',
fileName: 'vue-responsive-video-background-player',
},
rollupOptions: {
external: ['vue'],
output: {
// Provide global variables to use in the UMD build
// Add external deps here
globals: {
vue: 'Vue',
},
// in index.js we use a named + default export.
// We hide the error message with 'named'
exports: 'named',
},
},
},
},
// npm run build:demo for the demo page
demo: {
build: {
outDir: './demo/public/build',
rollupOptions: {
input: './demo/resources/js/app.js',
output: {
chunkFileNames: 'js/[name].js',
entryFileNames: 'js/[name].js',
},
},
},
},
};
const currentConfig = config[process.env.LIB_NAME];
if (currentConfig === undefined) {
throw new Error('LIB_NAME is not defined or is not valid');
}
// https://vitejs.dev/config/
export default defineConfig({
...currentConfig,
plugins: [
vue(),
cssInjectedByJsPlugin(),
],
});

Jest encountered an unexpected token when use the `amchart5` imports

I am getting this error by doing jest test with amchart5 integration.
Details:
C:\Users\BASHIMX5\Projects\Bitbucket\hf-ui\node_modules\#amcharts\amcharts5\index.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){export { Root } from "./.internal/core/Root";
^^^^^^
SyntaxError: Unexpected token 'export'
2 |
3 | import { ImplantReportComponent } from './implant-report.component';
> 4 | import * as am5 from '#amcharts/amcharts5';
| ^
5 | import * as am5xy from '#amcharts/amcharts5/xy';
6 | import am5themes_Animated from '#amcharts/amcharts5/themes/Animated';
7 |
at Runtime.createScriptFromCode (../../node_modules/jest-runtime/build/index.js:1728:14)
at Object.<anonymous> (src/app/pages/patient-account-management/component/implant-report/implant-report.component.spec.ts:4:1)
jest.preset:
const nxPreset = require('#nrwl/jest/preset').default;
module.exports = {
...nxPreset,
testMatch: ['**/+(*.)+(spec|test).+(ts|js)?(x)'],
transform: {
'^.+\\.(ts|mjs|js|html)$': 'jest-preset-angular'
},
transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)', "[/\\\\]node_modules[/\\\\](?!(#amcharts)\\/).+\\.js$", "^.+\\.module\\.(css|sass|scss)$"],
resolver: '#nrwl/jest/plugins/resolver',
coverageReporters: ['text', 'text-summary', "html", "cobertura"],
moduleFileExtensions: ['ts', 'js', 'html'],
globals: {
crypto: require('crypto'),
'ts-jest': {
tsconfig: '<rootDir>/tsconfig.spec.json',
stringifyContentPathRegex: '\\.(html|svg)$',
},
},
snapshotSerializers: [
'jest-preset-angular/build/serializers/no-ng-attributes',
'jest-preset-angular/build/serializers/ng-snapshot',
'jest-preset-angular/build/serializers/html-comment',
],
"reporters": ["default", "jest-junit"]
};
mock:
node_modules/
__mocks__/
├─ #amcharts/
│ ├─ amcharts5/
│ │ ├─ themes/
│ │ │ ├─ Animated.js
│ │ ├─ index.js
│ │ ├─ xy.js
But getting the above error. any help? I spend moreover 24 hr to fix. but no luck. I am running nx worksapce.
I was able to get past this by removing the es6 module regex in the transformIgnorePatterns settings. Also if you have other libraries/apps consuming this library, they also need to have the same regex settings in their transformIgnorePatterns.
const nxPreset = require('#nrwl/jest/preset').default;
module.exports = {
...nxPreset,
testMatch: ['**/+(*.)+(spec|test).+(ts|js)?(x)'],
transform: {
'^.+\\.(ts|mjs|js|html)$': 'jest-preset-angular'
},
transformIgnorePatterns: ['[/\\\\]node_modules[/\\\\](?!(#amcharts)\\/).+\\.js$', '^.+\\.module\\.(css|sass|scss)$'],
resolver: '#nrwl/jest/plugins/resolver',
coverageReporters: ['text', 'text-summary', "html", "cobertura"],
moduleFileExtensions: ['ts', 'js', 'html'],
globals: {
crypto: require('crypto'),
'ts-jest': {
tsconfig: '<rootDir>/tsconfig.spec.json',
stringifyContentPathRegex: '\\.(html|svg)$',
},
},
snapshotSerializers: [
'jest-preset-angular/build/serializers/no-ng-attributes',
'jest-preset-angular/build/serializers/ng-snapshot',
'jest-preset-angular/build/serializers/html-comment',
],
"reporters": ["default", "jest-junit"]
};

Webpack 4 - Module not found: Can't resolve node_modules

I am trying to bundle my nodejs express app with Webpack, I keep on getting the same error, will greatly appreciate help
node version 8.9.1
webpack version 4.41.2
Operating System Windows 10
My project structure
.
├── node_modules
├── package.json
├── README.md
├── src
│ ├── components
│ ├── index.js
|__ webpack-config.js
|
My Webpack config is following
var webpack = require('webpack');
import path from "path";
import nodeExternals from "webpack-node-externals";
module.exports = {
entry: {app:"./src/index.js"},
target: "node",
output: {
path: path.join(__dirname, 'webpack-build'),
filename: "bundle.js"
},
module:{
rules:[{
test: /\.(js)$/,
exclude: /(node_modules)/,
// flags to apply these rules, even if they are overridden (advanced option)
loader: "babel-loader",
// the loader which should be applied, it'll be resolved relative to the context
options: {
presets: ["es2015"]
},
}]
},
externals: [nodeExternals()]
};
Things I Have Tried
add webpack-node-externals to Externals property
Tried adding
resolve: {
root: [path.resolve(__dirname, 'src'), path.resolve(__dirname, 'node_modules')],
extensions: ['', '.js']
};
ERROR I GET

Getting Started with React-Hot-Loader

I am trying to use React Hot Loader in React. I installed react hot loader by running "npm install --save-dev react-hot-loader". I tried to follow the http://gaearon.github.io/react-hot-loader/getstarted/ but couldn't understand. I am attaching my webpack.config.js and package.json. I made changes as listed in document. But I am not able to see the changes I make in components on the fly. What is wrong?
webpack.config.js
var path = require('path');
var webpack = require('webpack');
module.exports = {
devServer: {
inline: true,
contentBase: './src',
port: 3000
},
devtool: 'cheap-module-eval-source-map',
entry: [
'webpack-dev-server/client?http://0.0.0.0:3000', // WebpackDevServer host and port
'webpack/hot/only-dev-server', // "only" prevents reload on syntax errors
'./dev/js/index.js' // Your appʼs entry point
],
module: {
loaders: [
{
test: /\.js$/,
loaders: ['react-hot','babel'],
exclude: /node_modules/
},
{
test: /\.scss/,
loader: 'style-loader!css-loader!sass-loader'
}
]
},
output: {
path: 'src',
filename: 'js/bundle.min.js'
},
plugins: [
new webpack.optimize.OccurrenceOrderPlugin(),
new webpack.HotModuleReplacementPlugin()
]
};
scripts from package.json
"scripts": {
"dev": "webpack",
"start": "webpack-dev-server"
}
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>React Webpack</title>
</head>
<body>
<div id="root"></div>
<script src="js/bundle.min.js"></script>
</body>
</html>
Ok, now you need to add the hot loading script to your html file, right before bundle like so:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>React Webpack</title>
</head>
<body>
<div id="root"></div>
<script src="http://localhost:3000/webpack-dev-server.js"></script>
<script src="js/bundle.min.js"></script>
</body>
</html>
It's under localhost:3000 because I see that in your webpack config. I usually just leave it under :8080, but I think it needs to be like this based on your config.

r.js with text files

I have a project at http://gifcept.com which is using require.js. I am in the process of optimicing the resources with r.js but I can't manage to get it working when I set inlineText: true.
I have the following tree of directories for testing purposes with r.js
└── uncompiled
├── js
│   ├── bookmarklet
│   ├── collections
│   ├── libs
│   │   ├── backbone
│   │   ├── jquery
│   │   ├── jquery.fileupload
│   │   ├── jquery.iframe-transport
│   │   ├── jquery.jscrollpane
│   │   ├── jquery.mousewheel
│   │   ├── jquery.scrolltofixed
│   │   ├── jquery.simple-dialog
│   │   ├── jquery.tag-it
│   │   ├── jquery.timeago
│   │   ├── jquery.ui
│   │   ├── modernizr
│   │   ├── require
│   │   └── underscore
│   ├── models
│   └── views
└── templates
My build.js file looks as follows
({
dir: "compiled",
baseUrl: "uncompiled/js",
stubModules: ['text'],
findNestedDependencies: true,
preserveLicenseComments: false,
optimizeAllPluginResources: true,
removeCombined: true,
optimize: "uglify",
inlineText: true,
modules: [
{
name: "main"
}
],
paths: {
jquery: 'libs/jquery/jquery-2.0.0',
underscore: 'libs/underscore/underscore-1.4.4',
backbone: 'libs/backbone/backbone-1.0.0',
modernizr: 'libs/modernizr/modernizr-2.6.2',
jqueryui: 'libs/jquery.ui/jquery.ui-1.10.3',
jquerytagit: 'libs/jquery.tag-it/jquery.tag-it-2.0',
jqueryiframetransport: 'libs/jquery.iframe-transport/jquery.iframe-transport-1.7',
jqueryfileupload: 'libs/jquery.fileupload/jquery.fileupload-5.31.6',
jquerysimpledialog: 'libs/jquery.simple-dialog/jquery.simple-dialog-0.0.1',
jqueryscrolltofixed: 'libs/jquery.scrolltofixed/jquery.scrolltofixed',
jquerytimeago: 'libs/jquery.timeago/jquery.timeago-1.3.0',
jquerymousewheel: 'libs/jquery.mousewheel/jquery.mousewheel',
jqueryjscrollpane: 'libs/jquery.jscrollpane/jquery.jscrollpane'
},
})
My main.js file looks like this
require.config({
baseUrl: "/js",
paths: {
jquery: 'libs/jquery/jquery-2.0.0',
underscore: 'libs/underscore/underscore-1.4.4',
backbone: 'libs/backbone/backbone-1.0.0',
modernizr: 'libs/modernizr/modernizr-2.6.2',
jqueryui: 'libs/jquery.ui/jquery.ui-1.10.3',
jquerytagit: 'libs/jquery.tag-it/jquery.tag-it-2.0',
jqueryiframetransport: 'libs/jquery.iframe-transport/jquery.iframe-transport-1.7',
jqueryfileupload: 'libs/jquery.fileupload/jquery.fileupload-5.31.6',
jquerysimpledialog: 'libs/jquery.simple-dialog/jquery.simple-dialog-0.0.1',
jqueryscrolltofixed: 'libs/jquery.scrolltofixed/jquery.scrolltofixed',
jquerytimeago: 'libs/jquery.timeago/jquery.timeago-1.3.0',
jquerymousewheel: 'libs/jquery.mousewheel/jquery.mousewheel',
jqueryjscrollpane: 'libs/jquery.jscrollpane/jquery.jscrollpane'
},
shim: {
jquery: {
exports: '$'
},
underscore: {
exports: '_'
},
backbone: {
exports: 'Backbone',
deps: ['underscore', 'jquery']
},
modernizr: {},
jqueryui: {
deps: ['jquery']
},
jquerytagit: {
deps: ['jquery', 'jqueryui']
},
jqueryiframetransport: {
deps: ['jquery']
},
jqueryfileupload: {
deps: ['jquery', 'jqueryui']
},
jquerysimpledialog: {
deps: ['jquery']
},
jqueryscrolltofixed: {
deps: ['jquery'],
},
jquerytimeago: {
deps: ['jquery'],
},
jquerymousewheel: {
deps: ['jquery'],
},
jqueryjscrollpane: {
deps: ['jquery', 'jquerymousewheel'],
}
}
});
require([
// Load our app module and pass it to our definition function
'app',
'events',
'modernizr',
'jquery',
'jqueryscrolltofixed',
'jqueryui',
'jquerytagit',
'jquerysimpledialog',
'jqueryiframetransport',
'jqueryfileupload',
'jquerytimeago',
'jquerymousewheel',
'jqueryjscrollpane'
], function(Application, Events){
...
...
});
An example of a define that uses text resources would be
define([
'underscore',
'backbone',
'helpers',
'events',
'router',
'views/destroyableView',
'text!/templates/comment.html'
], function(_, Backbone, Helpers, Events, Router, DestroyableView, CommentTemplate){
...
...
});
I have been able to get a compiled file both turning inlineText: false in the build.js and getting rid of the 'text!*' definitions. The error I get when inlineText is set to true and I keep the text resources definitions is the following:
Tracing dependencies for: main
RangeError: Maximum call stack size exceeded
In module tree:
main
app
views/appView
views/menuView
views/notificationCollectionView
views/notificationView
views/viewGifPopupView
views/commentCollectionView
views/commentView
text
Error: RangeError: Maximum call stack size exceeded
In module tree:
main
app
views/appView
views/menuView
views/notificationCollectionView
views/notificationView
views/viewGifPopupView
views/commentCollectionView
views/commentView
text
Any help would be really appreciated.
The only thing I can is to provide the small working example:
main.js
require.config({
paths : {
jquery : 'jquery-2.0.3',
backbone: 'backbone',
underscore: 'underscore'
},
shim : {
underscore: {exports: '_'},
backbone: {deps: ['underscore'], exports: 'Backbone'}
},
map : {
'*' : {
'text' : 'text' // real path tot text.js plugin
}
}
});
require(['jquery', 'backbone', 'text!./partials/view.html'], function($, Backbone, view) {
console.log('Type of $: ' + typeof $);
console.log('Type of Backbone: ' + typeof Backbone);
var element = $(view);
$('body').append(element);
});
index-prod.html
<!doctype html>
<html>
<head></head>
<body>
<script src="require.js"></script>
<script src="main-built.js"></script>
</body>
</html>
build.js
({
baseUrl : ".",
name : 'main',
mainConfigFile : "main.js",
out : "main-built.js",
findNestedDependencies : true,
inlineText : true,
stubModules: ['text'],
preserveLicenseComments: false,
optimizeAllPluginResources: true,
removeCombined: true,
optimize: "uglify",
})
index.html
<!doctype html>
<html>
<head></head>
<body>
<script data-main="main" src="require.js"></script>
</body>
</html>
partials/view.html
<div>Some view</div>
The build process goes without errors and text resource is inlined in main-built.js

Resources