Changes in webpack@
Let’s first talk about some of the main changes in webpack4 and previous versions:
1. Webpack no longer supports node v4. This is because the new webpack and affiliate plug-ins use the syntax of es6. The v4 version is not very good for es6, so it is not served anymore.
2. Start to adopt the idea of agreeing over configuration. Webpack@ sets default values for many options, such as the entrance is ./src and the output directory is ./dist. Of course, if you set it yourself, it will not block it. So when using webpack@, we can even package the same without this configuration file.
3. Split the webpack in the old version, divided it into webpack used to process logic and webpack-cli that provides executable commands. This is also the reason why some students will report the error of not finding the webpack-cli module after installing webpack into the new version.
4. Added mode option to distinguish the compilation environment and provide three options: development, production and none. In theory, this option is mandatory. In fact, if it is not specified, it also has a default value, but a warning will be given. If the official strongly recommends it, just specify it explicitly. There are two ways to specify, one is in the startup command:
./node_modules/.bin/webpack --mode production
Another option is to specify it in the configuration file, as follows:
var config = { mode: 'production' // Optional development, production and none}
5. Configuration changes are similar to deleting commonChunksPlugin and optimization is used instead of this. The usage of loader is also different from 1.15.0, but this upgrade was found in the previous version and was not brought by webpack@.
6. Performance optimization improves packaging performance. In addition, starting from webpack2, a Tree-shaking mechanism was introduced to propose modules that were not cited. Its principle is to re-establish a new dependency tree according to the reference relationship, and the modules that are not referenced will not be packaged into the final code. The previous compression optimization method was to hang all modules on the tree first, and then delete the uncited modules after analysis. Literally speaking, I think the original way is more like shaking a tree and shaking the useless ones down. The final compression of these two methods may be similar, but the design idea is completely from two directions.
7. Others. The above are some of the most important changes. For more detailed upgrade documents, please refer to the official description:/webpack/webpack/releases
Preface
Upgrading webpack4, you must read the documentation, especiallyUpdate instructions, don’t start to mess around by yourself after using webpack. After struggling, you may cry silently.
Changes in webpack4
webpack-cli withdrawal
The webpack-cli was dismantled separately. If the CLI was installed globally when used, it was OK to execute it directly.
webpack --config ./config/
If it is written in an npm hook, you will find some problems:
// "scripts": { "dev": "webpack --config ./config/" } //shall npm run dev
At this time, you will give a prompt:
One CLI for webpack must be installed. These are recommended choices, delivered as separate packages:
- webpack-cli (/webpack/webpack-cli)
The original webpack full-featured CLI.
- webpack-command (/webpack-contrib/webpack-command)
A lightweight, opinionated webpack CLI.
We will use "npm" to install the CLI via "npm install -D".
Which one do you like to install (webpack-cli/webpack-command):
If I didn’t have a global appearance, I would definitely realize that I wanted to choose one. The key to this pitfall is that I have a global appearance. So I was struggling there for a long time.
In fact, the official document begins with it.
npm install webpack webpack-cli --save-dev
After the installation is completed, continue to execute and find that there is warning:
WARNING in configuration
The 'mode' option has not been set, webpack will fallback to 'production' for this value. Set 'mode' option to 'development' or 'production' to enable defaults for each environment.
You can also set it to 'none' to disable any default behavior. Learn more: /concepts/mode/
Mode rules
Configuration rules: You must choose one between production and development so that webpack uses built-in optimizations for the corresponding mode
- Production supports all types of optimizations generated optimal bundles
- Development allows comments, prompts and eval devtoolsThe difference between devtool can be found here
- Production does not support watching and development is optimized for fast incremental reconstruction
- Production supports module concatenating (Scope Hoisting), which means scope improvement, and the module can be packaged in a function, which reduces the function declaration and the file size will also be reduced. detailedSee here for reference
- .NODE_ENV is set to distinguish environments (only in the build code rather than in the config)
- There is a hidden none mode mode that disables everything
usage:
1. In the configuration file:
= { entry: Entrys, mode: 'development' }
2. Pass the cli parameter into
webpack --mode=development
Both methods are feasible, but I encountered a very tricky problem that bothered me for several days. Finally, I knew the truth and tears fell down before I asked this question.
Zero configuration quick start
Because it has been criticized for being too tiring for configuration, and coupled with the pressure given by parcel, webpack4 also supports zero configuration packaging.
If there is no configuration file, the packaging will be started with ./src/ as entry by default.
If the file path of --config is configured or specified, it starts based on the corresponding configuration file.
Problem manifestation
In this article, the entry, mode and other related properties are configured, and the configuration file is as follows:
= { mode:'production', entry:{ app:'./src/', index:'./src/' }, output: { path: () + '/dist', filename: '[name].[hash].js', chunkFilename: '[name].[chunkhash].js', crossOriginLoading: 'anonymous' }, cache: true, devtool: 'cheap-source-map', externals: { jquery: 'jQuery' }, module: { rules: [ { test: /\.(js|jsx)?$/, include: [ (__dirname, "../src") ], exclude: [ 'node_modules', (__dirname, "../node_modules") ], use: [ { loader: 'babel-loader', options:{ presets:['es2015'] } } ] } ] }, resolve: { modules: [ 'node_modules' ], extensions: [".js", ".json", ".jsx", ".css"], }, devServer: { proxy: { // proxy URLs to backend development server '/api': 'http://localhost:3000' }, contentBase: (__dirname, "../dist"), hot: true, open:true }, plugins: [ new CleanWebpackPlugin(['dist']), new HtmlWebpackPlugin({ title:'test' }), new () ] }
Command configuration:
"scripts": { "build": "webpack --config " } //Execute packagenpm run build
I found that there will always be a prompt for selecting the mode type above, which is unacceptable. In addition, there is no ./src/ file, but my configuration entry is another file, which makes people inexplicably
ERROR in Entry module not found: Error: Can't resolve './src' in '/Users/****'
Based on the principle of following the prompts to solve problems, if you have fewer files, just create one (later I found that this kind of thinking is sometimes useful, sometimes you have to be cautious). Although the problem manifests consistently, the essence may be different.
It can be run after creation, but our configuration file does not seem to work.
The packaged file under dist is the default
Instead of the app and index we specified
In order to ensure that I entered the configuration file, I typed several logs and actually had outputs, which meant that I entered, and this problem was weird.
((__dirname, './src')) //Output the correct path = { //*****// }
Unified version
The initial guess is the version problem. Some issues mentioned that there are problems with some versions. Compared with the official demo, the problem still exists after locking the version.
Guess: There should be an error in the configuration file
Configuration Check
I pulled in and copied the most basic official configuration and tried it, but there were still problems that could not be solved.
Guess: There are problems with the local environment, npm, node and other versions
After checking, I found that the version is satisfying.
Run demo
Pull the demo to the local area and start it. The demo is packaged normally, indicating that the local environment is OK. Then the problem is obvious. There is a problem with my configuration file or project construction. Compared with the configuration items of the demo, there is no obvious problem with the configuration items. In this way, the configuration information is put into the demo. After modification, it is found that it works. I re-examined my configuration file. It is not only limited to the configuration part.
//What I write is, what I get from webpack is undefined. //Other's demo
Compatibility processing of webpack
webpack will merge the file passed in webpack --config with its default configuration to ensure that it does not make any errors in packaging itself. To prove our inference, the configuration file is left with only the output attribute and src/
= { output: { path: () + '/dist1', // Direct entry module zzz block name filename: '[name].js', // Non-entry modules, that is, they do not need to be packaged together, but may be used. // Isn't this loading on demand? chunkFilename: '[name].[chunkhash].js', crossOriginLoading: 'anonymous' } }
After executing, you will find that it is packaged under /dist1. So when the above is written incorrectly, the default configuration is completely adopted. The previous log is correct to execute before it is executed.
Ending
When encountering incredible problems, it is recommended to calm down and take a look and do not search blindly. In addition, the most reliable reference is official documents and examples, pay attention to comparing the version and environment. If there is no problem, then try various solutions online.
Here I will summarize and give myself a record, hoping that the solution can help others. I also hope everyone supports me.