Pass an argument to Webpack from Node.js - javascript

I'm trying to build both minified and unminified versions of my app (js and css) using Webpack.
This can be easily done via command-line interface using -p or --optimize-minimize switch:
webpack
webpack -p
However, I would like to perform these actions with just one command, so I decided to write a small Node.js script which would run both of these Webpack builds:
var webpack = require('webpack');
var config = require('./webpack.config');
webpack(config, callback); // Build unminified version
So the question is: can I pass the aforementioned -p argument to Webpack from the Node.js script in order to build the minified version? Or maybe there is a simpler way of solving my particular problem?
Of course, I can use child_process.exec(), but I don't think it's an authentic Node.js way.

Create your default config to webpack an unminified version. Run webpack with that config. Change the configuration from code and run webpack again. Here is a code example.
var webpack = require('webpack');
//assuming the config looks like this.
var config = {
entry: "./entry.js",
output: {
devtoolLineToLine: true,
sourceMapFilename: "./bundle.js.map",
pathinfo: true,
path: __dirname,
filename: "bundle.js"
},
module: {
loaders: [
{ test: /\.css$/, loader: "style!css" }
]
},
plugins: []
};
webpack(config).run(); // Build unminified version
config.output.filename = 'bundle.min.js'
config.plugins = [
new webpack.optimize.UglifyJsPlugin({
include: /\.min\.js$/,
minimize: true
})];
webpack(config).run(); // Build minified version

Key p is an alias to setting node environment variable process.env.NODE_ENV="production" as described here

Related

bundle an npm package AND convert it into an es module

I want to import chessground into a project of mine. It seems it's a CommonJS module, so i used browserify to import it into my web page.
browserify -r chessground > chessground.js
In order to use it in my webpage, I use
const Chessground = require('chessground').Chessground
but I saw in this project that they import it like
import {Chessground} from 'chessground'
I know they are douing with webpack, but for the life of me I can't figure out how to bundle an entire npm package into one file AND convert it into an ES module. Can anyone help me?
There is noway to bundle your packages without using a bundler like webpack or rollup.js.
If it is necessarily to use task runner you may find a way to make the bundler work with your task runner.
I had the same problem with gulpjs and wepack, and it was really painful to make it work. The solution was using a webpack and webpack plugins in gulpjs.
const webpack = require('webpack');
const webpackStream = require('webpack-stream');
const path = require('path');
const webapckJsConfig = {
mode: (process.env.APP_ENV === 'dev' && process.env.APP_DEBUG === 'true') ? 'development' : 'production',
devtool: (process.env.APP_ENV === 'dev' && process.env.APP_DEBUG === 'true') ? 'source-map' : false,
entry: {
// Website JS Files
'website/home.js': './resources/js/website/home.js',
'website/notfound.js': './resources/js/website/notfound.js',
'website/error.js': './resources/js/website/error.js',
// Admin JS Files
'admin/home.js': './resources/js/admin/home.js',
'admin/notfound.js': './resources/js/admin/notfound.js',
},
output: {
path: path.resolve(__dirname, 'public/'),
filename: '[name]',
},
module: {
rules: [
{
test: /\.m?js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
},
},
],
},
};
// JavaScript lint Cehck ✅ Convert 🔂 Compresse 🔄 Output ↪ 📁 public/js
async function scripts() {
return gulp
.src(`${JAVASCRIPT_DIR}/**/*.js`)
.pipe(webpackStream(webapckJsConfig), webpack)
.pipe(gulp.dest(`${JS_PUBLIC_DIR}`));
}
exports.scripts = scripts;
you can also check it here
You can of course take the webpack configuration and put them in external file, but you have to consider that you will confuse other developers because they will think webpack is independent and start to use it as an independent tool, so that's why I keep it in gulp.js.

Compiling or obfuscating node js

I have an existing node js backend that need to deploy on customer premise. I would like to compile/obfuscate the code before passing to client.
I do not know whether it is "compilable".
But at very least i want to have only single merged code into index.js file (other javascript file all remove) that is obfuscated before passing to client.
Is there any existing npm module that does that and how reliable that an obfuscated code work as it is then original code.
What are your company/ ways to deal with it when u need to pass an existing node js source code deployable at client premise.
I am much more looking at existing library that can automate the whole process.
eg: npx run obfuscate-code --entrypoint.js (it will search all the import/require from node js and compile everything.
Folder structure is as follow.
home
- controllers (folder)
- file1.js
- file2.js
- languages (folder)
- en.js
- services (folder)
- service1.js
- service2.js
- index.js (entry point)
You can make an executable using PKG (npm package) see => https://github.com/zeit/pkg
or webpack if you want to make a single js file that is minimized.
// webpack.config.js
const nodeExternals = require('webpack-node-externals');
module.exports = {
mode: 'production',
target: 'node',
externals: [nodeExternals()],
entry: {
'build/output': './src/index.js'
},
output: {
path: __dirname,
filename: '[name].bundle.js',
libraryTarget: 'commonjs2'
},
module: {
rules: [
{
test: /\.js$/,
use: {
loader: 'babel-loader',
options: {
presets: [
['env', {
'targets': {
'node': 'current'
}
}]
]
}
}
}]
}
};
By using nodeExternals you don't put external dependencies in the main js file but you refer to node_modules.
You can use both those 2 solutions using npm run ... by adding them to your scripts section in package.json

Can't require webpack on webpack.config

I'm trying to start a webapp with three.js, and i want to use webpack for bundling everything together, but i can't seem to figure out to require("webpack") on the webpak.config, i have to do this in order to use the webpack.providePlugin
Here is my webpack.config.js
var path = __dirname;
const webpack = require('webpack');
module.exports = {
entry: {
main: './main.js'
},
output: {
path: __dirname + '/dist/',
filename: '[name].bundle.js'
},
module: {
loaders: [
{
test: /\.js$/,
loader: 'babel-loader'
}
]
},
plugins: [
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery'
})
]
}
And here's the error that appears when i run webpack
Error on webpack run
The error only appears when i try to require webpack
I'm 99% sure the problem is that you're using an old version of Node.js.
Here's your error message:
/home/eloy/Sites/proyectomi/node_modules/webpack/lib/Compiler.js:10
const {
^
SyntaxError: Unexpected token {
If you're using Webpack 4.3 or 4.4 (the most current versions), then the line in question, line 10 of lib/Compiler.js, is the first line of this destructuring assignment:
const {
Tapable,
SyncHook,
SyncBailHook,
AsyncParallelHook,
AsyncSeriesHook
} = require("tapable");
A quick visit to node.green tells us that object destructuring wasn't supported in Node.js until version 6.4.0.
The webpack docs recommend using the current LTS release of Node.js:
Pre-requisites
Before we begin, make sure you have a fresh version of Node.js installed. The current Long Term Support (LTS) release is
an ideal starting point. You may run into a variety of issues with the
older versions as they may be missing functionality webpack and/or its
related packages require.
As of today (2018-03-30), that's Node.js 8.11.1.
1) var path = __dirname;
This line needs to be removed.
2) npm install webpack --save-dev
This will add webpack to dev dependencies.

Entry module not found: Error: Can't resolve './src/index.js'

I was installing a react startup app and added Webpack, but it says Can't resolve './src/index.js'.
Browser Shows
My Files Path and Package.json Contents
Webpack.config.js Contents
var debug = process.env.NODE_ENV !== "production";
var webpack = require('webpack');
var path = require('path');
module.exports = {
context: path.join(__dirname, "public"),
devtool: debug ? "inline-sourcemap" : false,
entry: "./src/index.js",
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /(node_modules|bower_components)/,
loader: 'babel-loader',
query: {
presets: ['react', 'es2016', 'stage-0'],
plugins: ['react-html-attrs', 'transform-decorators-legacy', 'transform-class-properties'],
}
}
]
},
output: {
path: __dirname + "/public/",
filename: "build.js"
},
plugins: debug ? [] : [
new webpack.optimize.DedupePlugin(),
new webpack.optimize.OccurrenceOrderPlugin(),
new webpack.optimize.UglifyJsPlugin({ mangle: false, sourcemap: false }),
],
};
Your base URL is path.join(__dirname, "public"), and your entry is ./src/index.js. Webpack tries to find ./src/index.js in public dir; obviously it does not exist. You should modify entry to ../src/index.js.
The other way I find out to fix this problem is to use path.resolve().
const path = require('path');
module.exports = {
mode: "production",
entry: path.resolve(__dirname, 'src') + 'path/to/your/file.js',
output: {
/*Webpack producing results*/
path: path.resolve(__dirname, "../src/dist"),
filename: "app-bundle.js"
}
}
This will make sure, webpack is looking for entry point in src directory.
By the way it's the default entry point. You can also change this entry point to your suitable location. Just replace the src directory with the other directory you want to use.
My webpack.config.js was named Webpack.config.js and the new cli was looking for something case-sensitive.
Webpack does not look for .js files by default. You can configure resolve.extensions to look for .ts. Don't forget to add the default values as well, otherwise most modules will break because they rely on the fact that the .js extension is automatically used.
resolve: {
extensions: ['.js', '.json']
}
The entry path is relative to the context. It's looking for a file in public/src/ when you want it to look for a path in just /src. Looking at the rest of your webpack.config.js it doesn't seem like you need the context line at all.
https://webpack.js.org/configuration/entry-context/
I had the same problem and found that it was caused by having installed create-react-app globally in the past using npm install -g create-react-app.
As create-react-app should now not be installed globally, I needed to uninstall it first using npm uninstall -g create-react-app and then install it in my project directory with npx create-react-app *my-app-name*.
My solution was to put App.js file on a components folder inside the src folder and keep the inde.js just inside the src one
I had same problem. And solutions was really 'at the top' I forgot to add module.exports inside my webpack.prod.js.
So instead of
merge(common, {
...
});
use
module.exports = merge(common, {
...
});

npm link with webpack - cannot find module

I'm trying to npm link a module to a project using webpack as its bundler. Of course, after trying many things, I keep getting this error:
ERROR in ./src/components/store/TableView.jsx
Module not found: Error: Cannot resolve module 'react-bootstrap-table'
Here are the exact steps I take when doing this:
1.) cd ../forks/react-bootstrap-table
2.) npm link
(success, checked ~/.nvm/.../node_modules/react-bootstrap-table for symlink and it's there)
3.) cd ../../projRoot/
4.) npm link react-bootstrap-table
(no errors thrown?, says successful link)
5.) node ./node_modules/webpack-dev-server/bin/webpack-dev-server.js
Solutions I've tried:
- https://webpack.github.io/docs/troubleshooting.html
- How to make a linked component peerDepdencies use the equivalent node_modules of the script being linked to?
- And many purple links on google serps
webpack.config.js
const webpack = require('webpack')
const path = require('path')
const ROOT_PATH = path.resolve(__dirname)
module.exports = {
devtool: process.env.NODE_ENV === 'production' ? '' : 'source-map',
entry: [
'webpack/hot/only-dev-server',
'./src/index.js'
],
module: {
loaders: [{
test: /\.jsx?$/,
exclude: /node_modules/,
loaders: ['react-hot','babel']
},
{
test: /\.scss$/,
loaders: ['style','css','sass'],
exclude: /node_modules/
},
{
test: /\.css$/,
loaders: ['style','css']
},
{
test: /\.(ttf|eot|svg|woff(2)?)(\?[a-z0-9]+)?$/,
loader: 'file-loader'
}
]
},
resolve: {
extensions: ['', '.js', '.jsx'],
fallback: path.resolve(__dirname, './node_modules')
},
resolveLoader: {
fallback: path.resolve(__dirname, './node_modules')
},
output: {
path: process.env.NODE_ENV === 'production' ? path.resolve(ROOT_PATH, 'app/dist') : path.resolve(ROOT_PATH, 'app/build'),
publicPath: '/',
filename: 'bundle.js'
},
devServer: {
contentBase: path.resolve(ROOT_PATH),
historyApiFallback: true,
hot: true,
inline: true,
progress: true,
stats: 'errors-only',
host: '192.168.1.115'
},
plugins: [
new webpack.HotModuleReplacementPlugin()
]
}
Notes:
1. this is the only symlink in the project
2. I run npm install inside forked version (also tried without, doesn't work)
3. I use NVM, but I have used symlinks before without webpack successfully.
I've been at this for a few days now, any help will be much appreciated.
I was facing a similar issue with webpack and ended up by adding this my webpack.config.js:
module.exports = {
resolve: {
symlinks: false
}
};
Here is the link to webpack docs. Since your question there happened a lot to webpack and their api, so I do not know how much relevance my answer still has according to your question. But for people facing this or a similar issue today this could be a solution. As to be seen, there are still people complaining about:
Webpack GitHub Issue 1643
Webpack GitHub Issue 1866
Also make sure you have bundle and yarn installed and executed in the linked package
Okay guys, this is specific to my use case, but make sure to follow all the instructions to completely build the library you are symlinking. Initially, I a npm install and gulp build, but that wasn't enough. I had to run a few extra commands to get the library to fully build.
Now it works! If you are still having issues, go through the documentation for each library you are symlinking, and use my webpack config as a template for resolving external libraries.
Just in case it's useful for others, the solution of adding the resolve.symlinks configuration to false suggested by #Beat was not enough in my case, I had to perform the following steps to solve it:
In the library:
Setup the libraries that are generating issues as peerDependencies in the package.json instead of dependencies or devDependencies, e.g. in my case react:
"peerDependencies": {
"react": "^16.8.6",
...
}
run npm install
build the library (in my case, with a rollup -c npm script
In my main app:
change the version of my library to point to my local project with a relative path in package.json, e.g.
"dependencies": {
"my-library": "file:../../libraries/my-library",
...
}
Add resolve.symlinks = false to my main app's webpack configuration
Add --preserve-symlinks-main and --preserve-symlinks to my package.json start script, e.g:
"scripts": {
"build": "set WEBPACK_CONFIG_FILE=all&& webpack",
"start": "set WEBPACK_CONFIG_FILE=all&& webpack && node --preserve-symlinks-main --preserve-symlinks dist/server.js",
}
run npm install
run npm run start

Categories

Resources