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
Related
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(),
],
});
I have a monorepo that includes both a front-end (CRA) React app and an Express API. They both use another package in the monorepo that is plain TS, but uses import statements. I use tsc to compile the TS -> JS for the React app, into a directory I call tscompiled, and for the Node app I further transpile the JS with babel to a directory called lib, so that all the import statements become requires.
So when I want to compile the React app, I need package.json for my dependency to use the tscompiled directory with its type definitions:
"main": "tscompiled/index.js",
And then when I want to compile the Express app, I need package.json for my dependency to use the lib directory:
"main": "lib/index.js",
This is a real kludge — can I get my Node Express app to handle import statements or transpile dependent packages within the monorepo automatically?
You should be able to use imports if you configure your project correctly. See the solutions mentioned in this SO thread.
I found a good solution for this problem, which was to use webpack for my Express API, with babel taking care of compiling TS and transpiling ES in dependent modules.
.babelrc:
{
"presets": ["#babel/preset-env", "#babel/preset-typescript"]
}
webpack.config.js:
const path = require('path')
const nodeExternals = require('webpack-node-externals')
module.exports = {
mode: 'production',
entry: path.resolve(__dirname, 'src') + '/index.ts',
output: {
path: path.resolve(__dirname, 'build'),
filename: '[name].js',
},
module: {
rules: [
{
test: /\.(ts|tsx|jsx|js)x?$/,
use: {
loader: 'babel-loader'
},
exclude: /node_modules/,
},
],
},
resolve: {
extensions: ['.ts', '.tsx', '.js', '.json', '.helpers.js'],
mainFields: ['main'],
},
target: 'node',
externals: [nodeExternals()]
}
I'm working with a monorepo node.js project with the following structure:
rootDir
packageA
packageB
packageC
I want to produce a bundle of packageB code using webpack and babel.js. packageA has a lot of exports however only one export is used by packageA, let's call the export utils.
When I run webpack it recognizes that packageB depends on packageA so webpack dependecnies graph now includes all modules exported by packageA in its index.js although only one is really needed. So all of the modules in packageA are being transpiled by babel.js which even includes the node_modules of packages included by files in packageA. I've run into numerous issues with transpiling node_modules with babel.js. They range from babel.js not being able to deal with non-Javascript files for which loaders do not exist, webpack not finding certain modules, having mixed esm and commonjs syntax inside some files and many others*.
Other issues could only be solved by commenting out 2 problematic modules exported by packageA.
As you can see the solution is not ideal and perhaps not sustainable for long. Is there a way to have webpack transpile packageA without transpiling its node_modules? I couldn't achieve this despite my numerous regex attempts. Below are my config files:
*I managed to solve the issue by adding modules: "commonjs" in babel config however this will disable webpack tree shaking mechanism which means that I need to use a separate babelrc for my project.
webpack.config.js
const path = require('path')
const webpack = require('webpack')
module.exports = {
mode: 'development',
target: 'node',
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'build')
},
devtool: 'source-map',
plugins: [
new webpack.IgnorePlugin(/^(hiredis|transifex)$/)
],
module: {
rules: [
{
test: /node_modules\/datauri\/index\.js$/,
loaders: ['shebang-loader', 'babel-loader']
},
{
test: /node_modules\/needle\/lib\/needle\.js$/,
loaders: ['file-loader', 'babel-loader']
},
{
test: /\.js?$/,
use: {
loader: 'babel-loader',
options: {
rootMode: 'upward'
}
},
include: [
path.resolve(__dirname, 'src'),
"/path/to/packageA",
"/path/to/packageC",
]
}
]
}
}
babel.config.js
module.exports = {
plugins: [
[
'#babel/plugin-proposal-decorators',
{
legacy: true
}
],
'#babel/plugin-syntax-dynamic-import',
'#babel/plugin-syntax-import-meta',
'#babel/plugin-proposal-class-properties',
'#babel/plugin-proposal-json-strings',
'#babel/plugin-proposal-function-sent',
'#babel/plugin-proposal-export-namespace-from',
'#babel/plugin-proposal-numeric-separator',
'#babel/plugin-proposal-throw-expressions',
'#babel/plugin-proposal-export-default-from',
'#babel/plugin-proposal-logical-assignment-operators',
'#babel/plugin-proposal-optional-chaining',
[
'#babel/plugin-proposal-pipeline-operator',
{
proposal: 'minimal'
}
],
'#babel/plugin-proposal-nullish-coalescing-operator',
'#babel/plugin-proposal-do-expressions',
'#babel/plugin-proposal-function-bind'
],
presets: [
[
'#babel/preset-env',
{
targets: {
node: 'current'
},
corejs: 3,
useBuiltIns: 'usage',
modules: "commonjs"
}
],
'#babel/preset-typescript'
],
env: {
debug: {
sourceMaps: 'inline',
retainLines: true
}
}
}
UPDATE: I just noticed that I'm not ignoring node_modules in babel.config.js so I added:
ignore: [
/node_modules/
]
to my babel.config.js. This allowed me to stop using modules: 'commonjs' so I guess this did have some effect but I still get errors when trying to run the bundle, errors that resulted from transpiling node_modules for example this error.
I am using the babel cli to compile es6 to es5
My package.json looks like this
"scripts":{
"build": "node ./scripts/generate.js && babel src -d es5 --copy-files"
}
I would like to be able to pass an option so that babel only compiles a certain folder. Currently it compiles everything in src and copies the output to an es5 folder.
Would it be possible to do something like
npm run build -folder-option=ExampleFolder
If there is anything unclear in my question please let me know.
make sure you npm install webpack before.
the simplest way to configure a webpack config with babel:
var path = require('path');
var webpack = require('webpack');
module.exports = {
entry: './js/app.js',
output: {
path: path.resolve(__dirname, 'build'),
filename: 'bundle.js'// export file
},
module: {
loaders: [
{
test: /\.js$/, //file with this ending will transpile by babel
include: [
path.resolve(__dirname, "src")
],
exclude: '/node_modules/', // ignore node_modules folder
loader: 'babel-loader',
query: {
presets: ['es2015']
}
}
]
},
devtool: 'source-map' // for the chrome debugger
};
I apologize for a code-heavy post.
I'm both new to Node, React and Webpack and a first-time sass-loader user. I'm running into some problems which seem to be trivial, but aren't.
ERROR in ./app/index.js Module not found: Error: Can't resolve
'waterbottle.scss' in '/Volumes/500GB/Webs/waterbottle/app' #
./app/index.js 4:13-40
I've tried placing the .scss file in the app folder, as well as fiddling with the .scss path.
Installation:
I installed sass-loader with
npm install sass-loader node-sass webpack --save-dev
webpack.config.js looks like this
var path = require('path');
var webpack = require('webpack');
var HTMLWebpackPlugin = require('html-webpack-plugin');
var HTMLWebpackPluginConfig = new HTMLWebpackPlugin({
template: __dirname + '/app/index.html',
filename: 'index.html',
inject: 'body'
});
module.exports = {
entry: __dirname + '/app/index.js',
module: {
loaders: [
{
test: /\.js$/,
loader: 'babel-loader',
query: {
presets: ['es2015', 'react']
}
}
],
rules: [
{
test: /\.scss$/,
use: ['style-loader', 'css-loader', 'sass-loader']
}
]
},
output: {
path: path.resolve(__dirname, 'build'),
filename: 'app.build.js'
},
plugins: [HTMLWebpackPluginConfig],
stats: {
colors: true
},
devtool: 'source-map',
watch: true
};
package.json includes this in devDependencies
"node-sass": "^4.5.3",
index.js contains
const scss = require("waterbottle.scss");
File structure:
My understanding is that sass-loader should automatically inject css into the dom. Many thanks in advance.
Sass loader documentation shows it like:
// webpack.config.js
module.exports = {
...
module: {
rules: [{
test: /\.scss$/,
use: [{
loader: "style-loader" // creates style nodes from JS strings
}, {
loader: "css-loader" // translates CSS into CommonJS
}, {
loader: "sass-loader" // compiles Sass to CSS
}]
}]
}
};
Solved. I needed to install:
npm install style-loader --save
npm install css-loader --save
And path to .scss file:
const scss = require("../scss/waterbottle.scss");
I'm very curious why this is not mentioned on sass-loader website, or better yet, installed automatically when running
npm install sass-loader node-sass webpack --save-dev