Webpack loader order misbehaved - javascript

I have used webpack ^2.2.1. I have added some loaders In my webpack.config.js file.
But my loader have not call in an order.
I used babel-loader for transform react-es6 codes to react-es5 codes. My custom-loader need react-es6 code. So I put my loader to first. I have print source content in each loaders. But every time first printing babel-loader info. After printing my info.
Is my loader order correct?
Help me! Thanks in advance!
// webpack.config.js
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, './build')
}
module: {
loaders: [
{
test: /\.js$/,
use: 'my-custom-loader'
},
{
test: /\.js$/,
use: [
{
loader: 'babel-loader',
options: {
presets: ['babel-preset-es2015', 'babel-preset-react']
}
}
]
}
]
}
}

Loaders in Webpack are used in order "right to left" so the last loader in your array is used first. Therefore babel is translating everything and your loader is second in line.
See: What is the loader order for webpack?
Try switching the order of your loaders (and of course use module.rules instead of module.loaders, so that you are using the new Pattern in Webpack 2)

Related

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 2 svg files give 404 error

Started working with webpack. In one of my css files I have an url to an svg file, but by using webpack I get 404 error when trying to load this file, tried few loaders first, second and last. Have no idea why its not working, can some one help me or give some info?
EDIT
entry: [
'./src\\main\\resources\\static\\webpack-js\\header.js'
],
output: {
path: path.join(__dirname, 'src/main/resources/static/dist'),
publicPath: '/src/main/resources/static/dist/',
filename: 'bundle.js',
libraryTarget: 'var',
library: 'EntryPoint',
},
module: {
loaders: [
{
test: /\.css$/,
loader: 'style-loader!css-loader'
},
{
test: /\.(jpe?g|png|gif|svg)$/,
loader: 'url-loader'
},
{
test: /\.js$/,
loader: ['buble-loader'],
exclude: '/node_modules/'
}
],
}
This is my module from webpack.config.js. I am using css file that is required in header.js (entry file). Now in the css file I have lines like this
.vismaicon-menu.vismaicon-info:before {
background-image: url(/static/css/img/vismaicons/top_menu/menu_info.svg);
}
As I mentioned I tried few things to load svg files but I'm getting 404 error. And yes url is correct and files are there, it works without webpack. Everything other than svg works in css files and I get things from it.
Changed my Loaders for svg to this one and giving bigger limit solved my problem.
{
test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
loader: "url-loader?limit=1000000&mimetype=image/svg+xml"
},

Using Webpack custom loader in loaders array

I am trying to build a Webpack custom loader:
module.exports = function(source) {
// Transform the source and return it
console.log('$$$$$$$$$$$$$$$$$$$$$');
return source;
};
Now, I want to use it in my loaders array, something like:
loaders: [
{test: /\.vm$/, loader: 'vm-loader', exclude: [/node_modules/, /dist/]}
]
I tried to use resolveLoader's alias, but it did not work:
resolveLoader: {
alias: {
"vm-loader": path.join(__dirname, "./lib/velocity-plugin")
},
root: [
path.join(__dirname, 'node_modules'),
path.resolve('./node_modules')
]
}
What Am I missing?
Answering my own question:
As it turned out, my custom loader doesn't work because webpack does not work on files which where not required. In my case those html/vm files are not required and not part of the bundle (they are rendered by the server).
My solution was adding gulp in order to have this working. Another (hacky) solution will be using this method

Load javascript in webpack

I am new to javascript dev in general and webpack in particular. I want to use this chess board module (https://github.com/oakmac/chessboardjs/) in my project. It sees to be exporting ChessBoard object. My project is using ES6, so I would love to be able to
import { ChessBoard } from 'chessboard'
or
import ChessBoard from 'chessboard'
I understand that I need some sort of loader for this. I have tried to add expose loader in the same way I use it for jQuery
{test: require.resolve("jquery"), loader: "expose?$!expose?jQuery"},
{test: require.resolve("chessboard"), loader: "expose?ChessBoard!./vendor/chessboard/js/chessboard-0.3.0.min.js"}
But I get "Error: Cannot find module 'chessboard'" error. Same if I replace ChessBoard with $. Not sure what I am doing wrong. Is expose even the right loader for what I am trying to do?
Here is my webpack config for reference (without the broken chessboard expose test)
var path = require('path');
var HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry: ['webpack/hot/dev-server', path.resolve(__dirname, 'app/main.js')],
output: {
path: path.resolve(__dirname, 'build'),
filename: 'bundle.js',
},
module: {
loaders: [
{test: require.resolve("jquery"), loader: "expose?$!expose?jQuery"},
{test: /\.jsx?$/, exclude: /(node_modules|bower_components)/, loader: 'babel', query: {presets: ['react', 'es2015']} },
/* CSS loaders */
{test: /\.css$/, loader: 'style!css'},
{test: /\.less$/, loader: 'style!css!less'},
/* font loaders for bootstrap */
{test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/, loader: 'url?limit=10000&mimetype=application/font-woff'},
{test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: 'url?limit=10000&mimetype=application/octet-stream'},
{test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'file'},
{test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: 'url?limit=10000&mimetype=image/svg+xml'},
],
},
plugins: [
new HtmlWebpackPlugin({
title: 'Test',
inject: false,
template: 'node_modules/html-webpack-template/index.ejs',
appMountId: 'app',
devServer: 'http://localhost:8080',
})
]
};
The problem seems to be that the chessboard.js is just a anonymous function and not a AMD or CommonJS module, and you may have to look at adding shims using webpack.
Not all JS files can be used directly with webpack. The file might be
in an unsupported module format, or not even in any module format.
https://github.com/webpack/docs/wiki/shimming-modules
Without seeing your entire webpack.config.js file it's tricky to say what the issue is. Basically you need to tell webpack to include `/node_modules/' into the list of paths it looks in for js modules.
You will need to add something like this to the resolve section of webpack.config.js.
modulesDirectories: ["node_modules"]
I guess you will need something like this in your webpack.config.js:
...
resolve: {
modules: [
'node_modules',
path.join( __dirname, 'node_modules' ),
path.resolve( './src' ),
...
You have to do two things:
1.) under plugins add:
new webpack.ProvidePlugin({
"window['jQuery']": "jquery"
})
2.) Install the script-loader plugin and import the script like this:
import 'script-loader!./chessboard.js';

webpack loaders and include

I'm new to webpack and I'm trying to understand loaders as well as its properties such as test, loader, include etc.
Here is a sample snippet of webpack.config.js that I found in google.
module: {
loaders: [
{
test: /\.js$/,
loader: 'babel-loader',
include: [
path.resolve(__dirname, 'index.js'),
path.resolve(__dirname, 'config.js'),
path.resolve(__dirname, 'lib'),
path.resolve(__dirname, 'app'),
path.resolve(__dirname, 'src')
],
exclude: [
path.resolve(__dirname, 'test', 'test.build.js')
],
cacheDirectory: true,
query: {
presets: ['es2015']
}
},
]
}
Am I right that test: /.js$/ will be used only for files with extension .js?
The loader: 'babel-loader', is the loader we install using npm
The include: I have many questions on this. Am I right that anything we put inside the array will be transpiled? That means, index.js, config.js, and all *.js files in lib, app and src will be transpiled.
More questions on the include: When files get transpiled, do the *.js files get concatenated into one big file?
I think exclude is self explanatory. It will not get transpiled.
What does query: { presets: ['es2015'] } do?
In webpack config there are multiple things for configuration, important ones are
entry - can be an array or an object defining the entry point for the asset you want to bundle, can be a js as test here says do it only for /.js$. Your application if has multiple entry points use an array.
include - defines the set of path or files where the imported files will be transformed by the loader.
exclude is self explanatory (do not transform file from these places).
output - the final bundle you want to create. if you specify for example
output: {
filename: "[name].bundle.js",
vendor: "react"
}
Then your application js files will be bundled as main.bundle.js and react in a vendor.js files. It is an error if you do not use both in html page.
Hope it helped
This documentation helped me understand better. Looks like it is for webpack 1 but still applies.
https://webpack.github.io/docs/configuration.html#module-loaders
Loaders
An array of automatically applied loaders.
Each item can have these properties:
test: A condition that must be met
exclude: A condition that must not be met
include: An array of paths or files where the imported files will be transformed by the loader
loader: A string of “!” separated loaders
loaders: An array of loaders as string
This example helped me understand what is going on. Looks like you use either include or exclude but not both. The test is a condition applied to all files. So if you include a folder, each file must pass the test condition. I have not verified this, but based on the example provided by the documentation, it look like that is how it works.
module: {
rules: [
{
// "test" is commonly used to match the file extension
test: /\.jsx$/,
// "include" is commonly used to match the directories
include: [
path.resolve(__dirname, "app/src"),
path.resolve(__dirname, "app/test")
],
// "exclude" should be used to exclude exceptions
// try to prefer "include" when possible
// the "loader"
loader: "babel-loader" // or "babel" because webpack adds the '-loader' automatically
}
]
}
1) Correct.
2) Correct.
3) Correct.
4) I am unsure. My webpack.config.js file includes an output key, and does bundle it all into one file:
output: {
path: path.resolve(__dirname, 'build'),
filename: 'bundle.js'
}
5) Correct.
6) This tells babel-loader what sort of transpile you want it to perform, as well as other compile options. So, for example, if you want it to transpile jsx as well + cache results for improve performance, you would change it to:
query: {
presets: ['react', 'es2015'],
cacheDirectory: true
}

Categories

Resources