Webpack minification -p errors - javascript

I'm testing my production javascript with minifcation using webpack. It works fine unminified but when i add the -p flag:
NODE_ENV=production ./node_modules/webpack/bin/webpack.js -p --progress --colors
I get warnings and there are javascript errors. Appears it's removing things it shouldn't. Can't figure out why.
Warnings:
WARNING in client.js from UglifyJs
Side effects in initialization of unused variable React [./~/fluxible/lib/Fluxible.js:12,0]
Dropping unused function $$$enumerator$$makeSettledResult [./~/fluxible/~/es6-promise/dist/es6-promise.js:361,0]
Side effects in initialization of unused variable $$utils$$now [./~/fluxible/~/es6-promise/dist/es6-promise.js:35,0]
Side effects in initialization of unused variable $$utils$$o_create [./~/fluxible/~/es6-promise/dist/es6-promise.js:38,0]
Dropping unused variable internals [./~/react-router/~/qs/lib/utils.js:6,0]
Dropping side-effect-free statement [./~/fluxible/addons/provideContext.js:6,0]
Side effects in initialization of unused variable Action [./~/fluxible/~/dispatchr/lib/Dispatcher.js:7,0]
Dropping unused variable internals [./~/react-router/~/qs/lib/index.js:9,0]
Here's my webpack.config.js
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var path = require('path');
module.exports = {
entry: [
'./client.js',
],
output: {
path: path.join(__dirname, 'assets'),
filename: 'client.js',
publicPath: '/assets',
},
plugins: [
new ExtractTextPlugin('styles.css'),
],
module: {
loaders: [
{ test: /\.(js|jsx)$/, exclude: /node_modules\/(?!react-router)/, loader: 'react-hot!babel-loader?stage=0' },
{
test: /\.scss$/,
loader: ExtractTextPlugin.extract(
// activate source maps via loader query
'css?sourceMap!' +
'sass?sourceMap'
)
},
// bootstrap
{
test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
loader: 'url-loader?limit=10000&mimetype=application/font-eot',
},
{
test: /\.(woff)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
loader: 'url-loader?limit=10000&mimetype=application/font-woff',
},
{
test: /\.(woff2)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
loader: 'url-loader?limit=10000&mimetype=application/font-woff2',
},
{ test: /\.js$/, include: /node_modules\/bootstrap/, loader: 'imports?jQuery=jquery' },
],
},
};
Thanks

The warnings you see are due to the fact that the loader is parsing your node_module dependencies. Since the only you have excluded is whatever matches /node_modules/(?!react-router)/
Instead of using the exclude option for module loaders, try only white listing the modules you want to load with include
exclude should be used to exclude exceptions
try to prefer include when possible to match the directories

Related

How to transpile a node_module with webpack in a web worker?

I am trying to include a node module (primitive-ellipsoid) in my wepback project. The module is not transpiled to es5 so throws an error when used in the browser:
Uncaught Error: Module parse failed: /Users/kevzettler/code/crashgiants/node_modules/primitive-ellipsoid/index.js Unexpected token (8:4)
You may need an appropriate loader to handle this file type.
| // Default to an oblate spheroid
| const { latSegments = 32, lngSegments = 64, rx = 2, ry = 1, rz = 1 } = {
| ...options
| };
|
This project is an older create-react-app webpack that is ejected.
"webpack": "3.5.1",
"webpack-dev-server": "2.8.2",
"webpack-manifest-plugin": "1.2.1",
It is using babel and babel-loader and worker-loader I have a webpack.config.dev.js with rules like:
rules: [
{
// "oneOf" will traverse all following loaders until one will
// match the requirements. When no loader matches it will fall
// back to the "file" loader at the end of the loader list.
oneOf: [
// Process JS with Babel.
{
test: /\.(js|jsx)$/,
include: [
paths.appSrc,
],
exclude: /\.worker.js$/,
loader: require.resolve('babel-loader'),
options: {
// This is a feature of `babel-loader` for webpack (not Babel itself).
// It enables caching results in ./node_modules/.cache/babel-loader/
// directory for faster rebuilds.
//cacheDirectory: true,
},
},
{
test: /\.worker.js$/,
exclude: /node_modules/,
use: [
'worker-loader',
require.resolve('babel-loader'),
]
}
]
I have babel configured in package.json with:
"babel": {
"plugins": [
"babel-plugin-transform-decorators-legacy"
],
"presets": [
[
"env",
{
"targets": "defaults"
}
],
"flow",
"react-app"
]
},
I have tried messing around with includes and excludes in the webpack.config.json to no success. I am confused if I need to focus on the worker-loader rule because it also uses the babel-loader or if the top level babel-loader gets applied as well.
UPDATE I only want to transpile the specific node_module/primitive-ellipsoid if I transpile the entire node_modules there is a bunch of other issues. I have tried
{
test: /\.(js|jsx)$/,
include: [
'node_modules/primitive-ellipsoid',
paths.appSrc,
],
exclude: /\.worker.js$/,
loader: require.resolve('babel-loader'),
options: {
// This is a feature of `babel-loader` for webpack (not Babel itself).
// It enables caching results in ./node_modules/.cache/babel-loader/
// directory for faster rebuilds.
//cacheDirectory: true,
},
},
But this has the same error.
Your first rule isn't finding primitive-ellipsoid. As mentioned in the comments above, try removing the include from your first build rule:
{
test: /\.(js|jsx)$/,
exclude: /\.worker.js$/,
loader: require.resolve('babel-loader'),
options: {
// This is a feature of `babel-loader` for webpack (not Babel itself).
// It enables caching results in ./node_modules/.cache/babel-loader/
// directory for faster rebuilds.
//cacheDirectory: true,
},
},
If that doesn't work, try adding another rule that will catch anything else as a fallback and see if it finds your library.

Webpack is importing modules from my machine's global `node_modules`. How do I get it to only import from my project's `node_modules`?

I'm migrating a project from using Grunt to using Webpack. This project uses jQuery. I noticed that the bundled code was working fine, even though I hadn't yet added jQuery to package.json, which seemed strange.
Looking at the output of webpack --mode=development --display-modules, I saw:
[../../../../../../../node_modules/jquery/dist/jquery.js] /Users/rothomas/node_modules/jquery/dist/jquery.js 274 KiB {index} [built]
That is: it seems at some point I ran npm install --global jquery, and Webpack is importing that jQuery. I don't want this to happen, because my teammates/server won't have jQuery installed in $HOME.
The obvious solution is for me to just remove jQuery from my $HOME/node_modules (no idea how it got there anyway), which will cause Webpack to fail until I add it to package.json, as expected.
But I'd like to know:
Why does Webpack use $HOME/node_modules? I understand this is the default behavior of Node package resolvers, but it seems very error-prone since I imagine many other developers keep their projects nested under $HOME.
How can I specify the scope within which Webpack should be trying to resolve modules?
(I looked at Webpack's documentation on resolvers, but it's not very clear to me.)
Here is my current Webpack config:
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
function pathTo(filepath) {
return path.join(__dirname, filepath);
}
module.exports = function (env, argv) {
return {
entry: {
'index': [
pathTo('src/scripts/index.js'),
pathTo('src/scss/index.scss'),
]
},
module: {
rules: [
{
exclude: /node_modules/,
loader: 'babel-loader',
options: {
presets: [
'#babel/env'
]
},
test: /\.js$/,
},
{
test: /\.(scss|css|sass)$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
},
{
loader: 'css-loader',
options: {
url: false,
},
},
{
loader: 'sass-loader',
options: {
sassOptions: {
outputStyle: 'expanded',
},
},
},
],
},
],
},
output: {
filename: '[name].js',
path: pathTo('web'),
},
plugins: [
new MiniCssExtractPlugin()
],
}
}
The problem is that your app is located inside the directory that has your global node_modules directory.
Webpack (and for that matter all node resolvers) will keep searching up your tree until it finds a directory that has a node-modules directory. then it will check in there for jquery. It continues doing this until it either finds what it's looking for, or if it reaches the root of your filesystem.

uglifyjs not minifying the files (Webpack)

I have been trying to use uglify option using webpack, but my resultant page's size remains the same without minification.I tried the following things,
webpack.config
var webpack = require('webpack');
const Uglify = require("uglifyjs-webpack-plugin");
module.exports = {
entry: __dirname + '/app/index.js',
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader'
}
]
},
output: {
filename: 'whattoname.js',
path: __dirname + '/build'
},
plugins: [
new Uglify()
]
};
I tried to set the mode to production
Ran the build using webpack -p command
Also with --optimize-minimizer command
The end file's size remains the same. Am I missing something here?
I had a similar issue, to resolve the problem I would suggest moving across to the inbuilt webpack uglifier as seen in the following example (no uglifier dependancy required):
var webpack = require('webpack');
module.exports = {
entry: __dirname + '/app/index.js',
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader'
}
]
},
output: {
filename: 'whattoname.js',
path: __dirname + '/build'
},
plugins: [
new webpack.optimize.UglifyJsPlugin({
minimize: true
})
]
};
If this does not resolve your issue I suggest several actions:
clean out your dist and recompile to insure the file is actually writing to dist
Inspect the dist code, to check if it appears uglified. It is possible your project was already uglifying the file somewhere else, which would mean the file size after uglification does not change
Adding the include: /\.js$/ field to your webpack.optimize.UglifyJsPlugin to specify precisely the targeted files
As for what caused this issue. I would suggest reading this comments posted here

Webpack gives eslint errors while using npm link

I have a multi-package project set up, where I have one JavaScript package that relies on a TypeScript library. Initially I installed Sinopia and was reinstalling the library every time I made changes to it. Then I saw npm link and thought that it would be easier for development. Unfortunately, when I linked the library (using npm link ../typescript-package) and built, it gives an error:
ERROR in ../typescript-package/dist/index.js
Module build failed: Error: No ESLint configuration found.
Since they are separate packages, I'm not quite sure why Webpack is trying to apply eslint to this package. Here is my webpack.common.js file (using merge and the dev vs prod configs shouldn't matter):
// webpack.common.js
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const babelOptions = {
presets: ['react', 'es2015', 'stage-0'],
sourceMaps: true,
retainLines: true,
};
module.exports = {
entry: {
solver: './source/index.jsx',
},
output: {
path: `${__dirname}/dist`,
filename: '[name].js',
publicPath: '/dist/',
},
resolve: {
modules: ['source', 'node_modules/'],
extensions: ['.js', '.jsx', '/index.jsx', '.json', '.ts', '/index.ts', '.scss', '/index.scss', '.css'],
},
module: {
rules: [
{
test: /\.jsx?$/,
use: [
{
loader: 'babel-loader',
options: babelOptions,
},
{
loader: 'eslint-loader',
options: {
emitWarnings: true,
},
},
],
exclude: /node_modules/,
}, {
test: /\.js$/,
loader: 'source-map-loader',
enforce: 'pre',
exclude: /node_modules/,
}, {
test: /\.scss$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: [{
loader: 'css-loader',
options: {
minimize: true,
localIdentName: '[local]_[hash:base64:5]',
},
}, {
loader: 'sass-loader',
options: {
includePaths: ['source/design'],
},
}],
}),
},
],
},
plugins: [
new ExtractTextPlugin({
filename: '[name].css',
allChunks: true,
}),
],
node: {
global: true,
},
};
I can also provide other config or package.json files if need be.
Way 1 - Webpack recommendation
According to webpack doc : https://webpack.js.org/configuration/module/#rule-conditions
Be careful! The resource is the resolved path of the file, which means symlinked resources are the real path not the symlink location. This is good to remember when using tools that symlink packages (like npm link), common conditions like /node_modules/ may inadvertently miss symlinked files. Note that you can turn off symlink resolving (so that resources are resolved to the symlink path) via resolve.symlinks.
So according to it you can disable symlink : https://webpack.js.org/configuration/resolve/#resolvesymlinks
Way 2 - Fancy hack
But maybe you need symlinks for your project. So, I use my eslint rule like this :
{
test: /\.js$/,
enforce: 'pre',
use: 'eslint-loader',
include: path.resolve(__dirname), // <-- This tell to eslint to look only in your project folder
exclude: /node_modules/
}
Plus obviously your own config of this loader.
I was dealing with this, as well. I'm not exactly sure why ESLint is looking for the config file in the external package (I would expect the local rc file to be adequate) but the symlink created by npm link takes the external package out of ./node_modules/, which otherwise would have been excluded by the loader.
The fix I've come up with is to copy the package into ./node_modules/. It then gets filtered out through the excludes rule in your Webpack config.
I know this is incredibly inelegant, and shouldn't be "good enough", but I've spent some time trying to get around this issue, and this is the best I was able to come up with. Until something better comes along, you can at least get moving on more pressing issues.
You can also add a .eslintignore file and add the real path to the linked module
// Content of .eslintignore
C:/path/to/your/linked/module
This is needed, because webpack resolves the module by its real path and not by the path in the node_modules folder (see webpack docs). Usually eslint ignores node_modules by default, but because of that it does not work here.

How to use compile ES6 (react) components and foundation sass with npm start

I followed this tutorial to setup a react project and I thought I nailed it. After installing everything works as it should.
But I have to create a website that uses foundation as a front-end lib. The tutorial I linked above runs server.js when I run npm start but foundation-cli uses the same command for compiling all foundation sass code to css.
At the moment when I run npm start it only runs react and not foundation. How can I run foundation too? can I make it so that it'll automatically run both?
Since you are already using Webpack, I would suggest you to use one of the loaders for it and compile your CSS with it. This one seems like it can do that for you.
This is not tested, but I assume you can add it to your Webpack config like this:
// be sure to install it with
// npm install sass-loader node-sass --save-dev
const path = require('path');
module.exports = {
context: path.join(__dirname, 'src'),
entry: [
'./main.js',
],
output: {
path: path.join(__dirname, 'www'),
filename: 'bundle.js',
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: [
'babel-loader',
],
},
{
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
}
}
],
},
resolve: {
modules: [
path.join(__dirname, 'node_modules'),
],
},
};

Categories

Resources