pass option to npm script to just compile specific folder babel - node.js

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
};

Related

How to include only specific module in webpack without transpiling its dependencies?

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.

NodeJS+Webpack+Docker project on WSL throwing errors with native 'fs' library

I have a NodeJS project that I'm building with Webpack and running inside a Docker container. This was being developed in a Linux environment, but I decided to try to move it to WSL (Windows subsystem for Linux) because that would make things easier for the dev team. Getting it to run on WSL has been difficult though.
Currently the project builds with no problems, and Docker also seems to be running smoothly. However, when I open the project on a browser, nothing loads. On the console is the following error message:
Uncaught TypeError: Cannot read property 'native' of undefined
at Object../node_modules/fs-extra/lib/fs/index.js (index.js:107)
at __webpack_require__ (bootstrap:19)
at Object../node_modules/fs-extra/lib/index.js (index.js:6)
at __webpack_require__ (bootstrap:19)
at Object.<anonymous> (RollingFileWriteStream.js:2)
at Object../node_modules/streamroller/lib/RollingFileWriteStream.js (RollingFileWriteStream.js:265)
at __webpack_require__ (bootstrap:19)
at Object../node_modules/streamroller/lib/index.js (index.js:2)
at __webpack_require__ (bootstrap:19)
at Object.<anonymous> (file.js:3)
When I check index.js:107, I see the following lines:
// fs.realpath.native only available in Node v9.2+
if (typeof fs.realpath.native === 'function') {
exports.realpath.native = u(fs.realpath.native)
}
However, all node versions I have running are 10+. My base image is node:12 (more specifically, version 12.13.0). Nodejs and npm versions on WSL are:
me#computer:.../addin$ nodejs --version
v12.11.1
me#computer:.../addin$ npm --version
6.12.0
And NodeJS on windows is:
PS H:\> node --version
v10.15.3
I'm not sure if this is relevant, but here are my webpack config files:
webpack.server.config.js:
const path = require('path')
const webpack = require('webpack')
const nodeExternals = require('webpack-node-externals')
module.exports = {
entry: {
server: './src/server/server.js',
},
output: {
path: path.join(__dirname, 'dist'),
publicPath: '/',
filename: '[name].js'
},
target: 'node',
node: {
// Need this when working with express, otherwise the build fails
__dirname: false, // if you don't put this is, __dirname
__filename: false, // and __filename return blank or /
fs: 'empty'
},
externals: [nodeExternals()], // Need this to avoid error when working with Express
module: {
rules: [
{
// Transpiles ES6-8 into ES5
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
}
]
}
}
webpack.config.js:
const path = require("path")
const webpack = require('webpack')
const HtmlWebPackPlugin = require("html-webpack-plugin")
module.exports = {
entry: {
main: './src/js/index.tsx'
},
output: {
path: path.join(__dirname, 'dist'),
publicPath: '/',
filename: '[name].js'
},
target: 'web',
devtool: 'source-map',
resolve: {
extensions: ['.ts', '.tsx', '.html', '.js']
},
module: {
rules: [
{
test: /\.tsx?$/,
exclude: /node_modules/,
use: 'ts-loader'
},
{
test: /\.js$/,
exclude: /node_modules/,
loader: "babel-loader",
},
{
// Loads the javacript into html template provided.
// Entry point is set below in HtmlWebPackPlugin in Plugins
test: /\.html$/,
use: [
{
loader: "html-loader",
//options: { minimize: true }
}
]
},
{
test: /\.css$/,
use: [ 'style-loader', 'css-loader' ]
},
{
test: /\.(png|svg|jpg|gif)$/,
use: ['file-loader']
}
]
},
plugins: [
new HtmlWebPackPlugin({
template: "./src/html/index.html",
filename: "./index.html",
excludeChunks: [ 'server' ]
})
]
}
And the build command is:
rm -rf dist && webpack --mode development --display-error-details --config webpack.server.config.js && webpack --mode development
I'm out of ideas on how to fix this. I have tried removing and reinstalling nodejs, deleting all docker images, etc. Any suggestions would be much appreciated.
Fixed by installing this npm package, importing it on server.js, and monkey-wrenching:
var rp = require('fs.realpath')
rp.monkeypatch()
Unfortunately fixing it didn' give me any more insight on what's wrong with WSL and node, but at least it works.
EDIT:
Since this question seems to be relevant to some, I have since discovered that the real problem is that I was trying to use fs in a class that was bundled with target: 'web' (the second config file I posted). This is another part of the code, and it didn't occur to me that this could be the problem.
The webpack.config.js I posted originally is for an expressJS server, while this other part of the code was for the frontend of the application.
From what I understand, target: 'web' tells Webpack not to bundle and NodeJS functions because this code will be run in a browser. target: 'node' is appropriate for code that will run in a node environment (i.e. an expressJS server, that will run on the backend)
I hope this helps people who are running into this problem.
Do you have jquery in your package.json? I remember getting that error with Create-React-App when I forget to add the jquery cdn to index.html

Sass-loader with Webpack, React and Babel not working

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

Why do I have to run "webpack" command again n again?

I am working with a React project. Every time I make any change in any of the .js files, I have to run the "webpack" command in the terminal again to get the changes reflect on browser. Is there any way so that I cannot have to run the "webpack" command again n again.
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: './dev/js/index.js',
module: {
loaders: [
{
test: /\.js$/,
loaders: ['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()
]
};
You need webpack-dev-server and react hot loader, also you need development config. Please take a look at this page ReactHotLoader and if you find it complex comment here and i will provide you more links that could be helpful.
Also please take a look at this example Github:React-redux-app, this could help you set up your development env.
It's simple. Just run webpack with -w flag to make it watch for changes and rebuild every time on change.
webpack -w

Webpack not resolving babel or babel-loader installed globally

I have been trying a new project and wanted to use webpack and modules to split code. I have installed npm followed by installing webpack as follows
npm install -g webpack
npm install -g babel-cli babel-core babel-loader babel-presets-es2015
Now in my project I have created a new config.js file containing below content.
module.exports = {
entry: './src/js/app.js',
output: {
filename: 'dist/js/bundle.js'
},
module: {
loaders: [
{
test: /\.js$/,
loader: 'babel-loader'
}
]
},
}
However, I always get an error saying
ERROR in Entry module not found: Error: Cannot resolve module 'babel-loader'
In other words, how to make webpack resolve globally installed packages?
At last got it going. Not sure if it is the right way. However,
this is how my project is setup and working. I suppose there should be a better way of setting presets for module loaders.
my-project
src
js
entry.js
module1.js
module2.js
dist
index.html
js
bundle.js
Now, my current config.js setup is as shown below.
module.exports = {
resolve: {
fallback: '/usr/local/lib/node_modules'
},
resolveLoader: {
fallback: '/usr/local/lib/node_modules'
},
entry: './src/js/app.js',
output: {
filename: 'dist/js/bundle.js'
},
module: {
loaders: [
{
test: /\.js$/,
loader: 'babel-loader',
query: {
presets: ['/usr/local/lib/node_modules/babel-preset-es2015']
}
}
]
},
}

Resources