1. Hot replacement of the module
Reference address – official website
1.1 enable HMR
Enabling this feature requires updating the configuration of Webpack-dev-server and using the built-in HMR plug-in for WebPack.
webpack.config.js
module.exports = {
// ...
devServer: {
// ...
hot: true}};Copy the code
worker.js
if (module.hot) {
module.hot.accept('./print.js'.function() {
console.log('Accepting the updated printMe module! '); printMe(); })}Copy the code
Pay attention to the point
1.2 HMR modifies the stylesheet
CSS module hot update, with style-loader.
2. Tree shaking
See 1- official website, see 2- blog
2.1 sideEffects
false
All file code has no side effects- Array, specifying file code is a side effect
A “side effect” is defined as code that performs special behavior when importing, rather than just exposing one or more exports. For example, polyfill, which affects the global scope, usually does not provide export. No tree Sharking with side effects!
Note that any imported files are affected by Tree shaking. This means that if you use a csS-loader like this in your project and import a CSS file, you need to add it to the Side Effect list to avoid accidentally removing it in production mode.
{
"name": "your-project"."sideEffects": [
"./src/some-side-effectful-file.js"."*.css"]}Copy the code
You can also set “sideEffects” in the Module. rules configuration option
2.2 Compressed Output
Starting with Webpack 4, it is also easy to switch to compressed output via the “mode” configuration option, simply set to “Production”.
webpack.config.js
module.exports = {
// ...
mode: "production"
};
Copy the code
2.3 Tree Sharking Conditions
- Using ES2015 module syntax (i.e
import
和export
) - In the project
package.json
File, add onesideEffects
The entrance - Introduce a minifier that can remove unreferenced dead code (e.g
UglifyJSPlugin
Webpack4 can be set up at the beginningmode
:"production"
Instead of)
3. devtool
Reference – Official website
In production, when using uglifyjs-webpack-plugin, you must provide sourceMap: true to enable Source Map support.
You are encouraged to enable Source maps in production, as they are useful for debugging source code and running benchmark tests.
3.1 For the development environment
eval
– Map to transformed codeeval-source-map
– The number of lines will map correctly and will map to the original code.cheap-eval-source-map
– similar to theeval-source-map
, used by each moduleeval()
The execution. This is aCheap “source mapBecause it does not generate column mapping, it just ** maps the number of rows. It ignores the source map from the Loader, ** and only displays the translated code, as ineval
Devtool.cheap-module-eval-source-map
– similar to thecheap-eval-source-map
And, in this case,The source map from the Loader gets better results. However, the Loader source map is simplified to one mapping per row.
3.2 For the production environment
These options are commonly used in production environments:
-
(None) (omits devtool option) – Does not generate source map. This is a good choice.
-
Source-map – The entire source map is generated as a single file. It adds a reference comment to the bundle so that development tools know where to find it.
You should configure your server to not allow ordinary users to access the Source map file!
-
Hidden-source-map – same as source-map, but does not add a reference comment to the bundle. This option is useful if you only want the Source Map to map the error stack trace from the error report, but do not want to expose your Source map for browser development tools.
You should not deploy the Source Map file to the Web server. Instead, use it only for error reporting tools.
-
Nosource-source-map – The source map created does not contain sourcesContent. It can be used to map stack traces on the client without exposing all the source code. You can deploy the Source Map file to the Web server.
This still exposes the decompiled file name and structure, but it does not expose the original code.
3.3 Specific Scenarios
The following options are not ideal for both development and production environments. They are needed in specific scenarios, for example, for third-party tools.
inline-source-map
– Source map is converted to DataUrl and added to the bundle.cheap-source-map
– If no column mapping source map is available, the loader source map is ignored.inline-cheap-source-map
– similar to thecheap-source-map
, but the Source map is converted to the DataUrl and added to the bundle.cheap-module-source-map
– There is no column mapping source map and loader source map is simplified to one mapping for each row.inline-cheap-module-source-map
– similar to thecheap-module-source-map
But the Source Mapp converts to the DataUrl and is added to the bundle.
4. Specify environment variables
Reference – Official website
4.1 Basic Usage
Many libraries will associate the process.env.node_env environment variable to determine what should be referenced in the library. For example, when not in production, some libraries may add additional logging and tests to make debugging easier. In fact, ** When using process.env.node_env === ‘production’, some libraries may optimize their code for user-specific environments to remove or add important code. ** We can define this variable for all dependencies using the DefinePlugin built into WebPack:
NODE_ENV attributes:
- This variable is not directly present in pocess. Env, but is set.
- You can distinguish between a development environment and a production environment by determining this variable.
webpack.prod.js
const webpack = require('webpack');
const merge = require('webpack-merge');
const common = require('./webpack.common.js');
module.exports = merge(common, {
plugins: [
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('production')]}}));Copy the code
Technically, NODE_ENV is a system environment variable exposed by Node.js to execute scripts. Typically used to determine the behavior of server tools, build scripts, and client libraries in development vs. production (dev-VS-PROd) environments. However, contrary to expectations, process.env.node_env cannot be set to “production” in the build script webpack.config.js, see #2537.
For example,process.env.NODE_ENV === 'production' ? '[name].[hash].bundle.js' : '[name].bundle.js'
Such conditional statements, in the WebPack configuration file, do not work as expected.
Any native code at/SRC can be associated with the process.env.node_env environment variable, so the following checks are also valid:
src/worker.js
import { cube } from './math.js';
if(process.env.NODE_ENV ! = ='production') {
console.log('Looks like we are in development mode! ');
}
Copy the code
4.2 is it?
Why does webpack website say:
process.env.NODE_ENV === ‘production’ ? Conditional statements like ‘[name].[hash].bundle.js’ : ‘[name].bundle.js’ do not work as expected in webPack configuration files.
However, the MiniCssExtractPlugin website can be used as follows:
constdevMode = process.env.NODE_ENV ! = ='production'
Copy the code
4.3 to reassure
Reference – netizen blog
- In its initial state”The configuration file ” 和 ” SRC file below“The output of
process.env.NODE_ENV
Values areundefined
. - The variables defined in the WebPack Config file are for the files you will be packaging. The configuration is as follows:
/ / way
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('production')})2 / / way
{
mode: 'production'
}
Copy the code
If only NODE_ENV is set, mode is automatically set.
- How to in
webpack
Obtained from the configuration fileNODE_ENV
We can define the related parameters according to the different values.corss-env
, add the following configuration to package.json:
"scripts": {
"build-cross-env":"cross-env NODE_ENV=production webpack"
}
Copy the code
With cross-env NODE_ENV=production, the information is passed to the webpack configuration file, which is not accessible below SRC.
5. Code separation
Reference – Official website
5.1 an overview of the
Separate the code into different bundles, and you can load these files on demand or in parallel. Code separation can be used to obtain smaller bundles and control resource load priorities, which, when used properly, can greatly affect load times.
There are three common ways to separate code:
- Entry starting point: Manually detach code using the Entry configuration.
- Prevent duplication: Use CommonsChunkPlugin to deduplicate and separate chunks.
- Dynamic import: Separation of code through inline function calls to modules.
5.2 Dynamic Imports
Webpack provides two similar techniques when it comes to dynamic code splitting. For dynamic imports, the first and preferred approach is to use the import() syntax that conforms to the ECMAScript proposal. The second is to use webpack-specific require.ensure. Let’s try the first one…
Import () calls will use promises internally. If you use import() in older browsers, remember to use a polyfill library (such as ES6-Promise or promise-polyfill) to shim promises.
worker.js
/ / way
const _ = await import(/* webpackChunkName: "lodash" */ 'lodash');
2 / / way
import(/* webpackChunkName: "print" */ './print').then(module= > {
var print = module.default;
print();
});
Copy the code
Note that when the IMPORT () method of the ES6 module is called (importing the module), it must point to the module’s.default value, as ** is the actual Module object * returned after the promise is processed. *
webpack.config.js
output: {
filename: '[name].bundle.js'.chunkFilename: '[name].bundle.js'.path: path.resolve(__dirname, 'dist')}Copy the code
5.3 bundle analysis
Reference – official website
6. The cache
6.1 Differences between Hash, Chunkhash, and Contenthash
Reference – netizen blog
hash
Relative to the entire WebPack build project, the hash value is different each time the project builds, even if the project file has not made ** “any changes” **.
There are changes, because every webPack compilation injects the Webpack runtime code, causing the entire project to change, so the hash value changes every time.
chunkhash
** According to different Entry files, dependency files are parsed, corresponding chunks are constructed, and corresponding hash values are generated. ** In the production environment, separate some public libraries from the program entry files, package them separately, and use chunkhash to generate hash values, so as long as the code of the public library is not changed, the hash value can be guaranteed not to be affected.
After using chunkhash for CSS, it shares chunkhash with the chunk that depends on it. After testing, it will be found that the CSS and JS file name have the same value of chunkhash. Js and CSS interact with each other.
Contenthash is best used for CSS files.
contenthash
Contenthash indicates the hash value generated by the file content. The contenthash value varies with the content.
6.2 Image/font cache
For static resources such as images and fonts, the corresponding file hash value is calculated by the corresponding file-loader.
So what hash values are used for these static files?
It’s the hash property value. This hash is not a webpack-built hash for each project, it is calculated by file-loader from the contents of the file, not a Webpack-built hash.
7. Webpack configuration Types
Reference – Official website
7.1 Export as a function
module.exports = function(env, argv) {
return {
mode: env.production ? 'production' : 'development'.devtool: env.production ? 'source-maps' : 'eval'.plugins: [
new webpack.optimize.UglifyJsPlugin({
compress: argv['optimize-minimize'] // It can only be passed -p or --optimize-minimize}})]; };Copy the code
When a WebPack configuration object is exported as a function, an “environment object” can be passed up. It can also be configured using cross-env NODE_ENV=production webpack” in [Specifying environment variables](#4. Specifying environment variables)
webpack --env.NODE_ENV=local --env.production --progress
Copy the code
Production sets –env.production to true by default if the env variable is set and no value is assigned. There are other syntaxes you can use. See the Webpack CLI documentation for more information.
7.2 Exporting a Promise
Webpack will run the functions exported from the configuration file and wait for the Promise to return. Facilitate the need to load the required configuration variables asynchronously.
module.exports = (a)= > {
return new Promise((resolve, reject) = > {
setTimeout((a)= > {
resolve({
entry: './app.js'./ *... * /})},5000)})}Copy the code
7.3 Exporting a Configuration Object
7.4 Exporting Arrays, Multiple configuration objects
8. Webpack-dev-server refresh mode inline and iframe details
Reference – Blog
iframe
- Embedded one in the web page
iframe
To inject our own application into thisiframe
. - There is a prompt box at the top of the page that displays status information about the build process.
- To load the
live.bundle.js
The file is not only creatediframe
The tag also containssocket.io
theclient
Code to andwebpack-dev-server
forwebsocket
Communication, so as to complete automatic compilation packaging, page automatic refresh function.
inline
- The build message is displayed in the browser console.
socket.io
theclient
The code is packaged into your package (bundle
), in order towebpack-dev-server
forwebsocket
Communication, so as to complete automatic compilation packaging, page automatic refresh function.- However, each entry file will be inserted into one of the above scripts to make the packaged
bundle
The files are bloated.
conclusion
Iframe mode
andInline mode
The final effect is the same, are listening to the file changes, and then push the compiled file to the front end, complete the pagereload
.- By setting the
devServer.inline
Switch between two modes. The default value isinline
Mode. - This parameter is recommended when using the HMR function
inline mode
.
Mode of 9.
Reference – Official website
Remember that setting only NODE_ENV does not automatically set mode.
9.1 usage
Only provide the mode option in the configuration:
module.exports = {
mode: 'production'
};
Copy the code
Or from the CLI parameter:
webpack --mode=production
Copy the code
9.2 production
The value of process.env.node_env is set to production. Enable FlagDependencyUsagePlugin FlagIncludedChunksPlugin, ModuleConcatenationPlugin NoEmitOnErrorsPlugin, OccurrenceOrderPlugin SideEffectsFlagPlugin and UglifyJsPlugin.
mode: production
// webpack.production.config.js
module.exports = {
+ mode: 'production',
- plugins: [
- new UglifyJsPlugin(/ *... * /),
- new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("production")}), -new webpack.optimize.ModuleConcatenationPlugin(),
- new webpack.NoEmitOnErrorsPlugin()
- ]
}
Copy the code
9.3 development
The value of process.env.node_env is set to development. Enable NamedChunksPlugin and NamedModulesPlugin.
mode: development
// webpack.development.config.js
module.exports = {
+ mode: 'development'
- plugins: [
- new webpack.NamedModulesPlugin(),
- new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("development")}), -]}Copy the code
10. output
10.1 the output. The library
For general-purpose libraries, we want it to be compatible with different environments, such as CommonJS, AMD, Node.js or as a global variable. To make your library usable in all consumption environments, add the Library attribute to output.
To make the Library compatible with other environments, you also need to add the libraryTarget attribute to the configuration file. This is the option to control how the library is exposed in different ways. The default option for output.libraryTarget is var.
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'webpack-numbers.js'.library: 'webpackNumbers'
library: 'webpackNumbers'.libraryTarget: 'umd'
},
Copy the code
10.2 the output. PublicPath and devServer. PublicPath
PublicPath and devServer.publicPath
The purpose of devServer.publicPath is to determine what path external users can use to access files built in memory through devServer. The explicit value of the output.publicPath field is used (if output.publicPath has a value, its default value is used otherwise). The purpose of output.publicPath is to generate a prefix for a built file that meets specific requirements and provide this prefix to the required resolver, plugin, or other configuration fields.
Filename in HtmlWebpackPlugin also depends on public.publicPath
See the blog – you’ll be sure to read the meaning of devServer.publicPath, output.publicPath, and output.path
10.3 the output path
This field only works in the production configuration. If you try it out, you’ll see that in the development configuration, no matter what value you set it to (it must be a compliant absolute address), it won’t affect your access to the files built in memory at development time. So in the development configuration, just ignore it. Also, its default value is’ path.resolve(__dirname, ‘./dist’).
11. webpack.optimize.ModuleConcatenationPlugin
New in Webpack 3: Scope collieries
In the past, one of the trade-offs in Webpack packaging was to package each module in the bundle individually into a closure. These packaging functions make your JavaScript process more slowly in the browser. In contrast, tools like Closure Compiler and RollupJS can hoist or precompile all modules into a Closure, speeding up your code execution in the browser. This plugin implements the above precompiled functionality in Webpack.
12. devServer
The files devServer builds are in memory, not on your computer’s disk, but if the desired file is not found in memory, devServer will try to find it on your computer’s disk based on the path of the file.
If a file with the same file name exists in the real disk path under memory and contentBase at the time of development, devServer returns the one in memory
12.1 devServer.historyApiFallback
historyApiFallback: {
rewrites: [{from: /. * /.to: path.posix.join(devConfig.assetsPublicPath, 'index.html')},],},Copy the code
When using the HTML5 History API, any 404 response may need to be replaced with index.html. Enable by passing in the following:
historyApiFallback: true
Copy the code
This behavior can be further controlled by passing in an object, such as using the rewrites option:
historyApiFallback: {
rewrites: [{from: $/ / ^ \ /.to: '/views/landing.html' },
{ from: /^\/subpage/.to: '/views/subpage.html' },
{ from: / /..to: '/views/404.html'}}]Copy the code
12.2 devServer.publicPath
Determines the path through which the built file can be accessed externally.
[查看](#10.2 output.publicPath and devserver. publicPath)
13. Vue-cli common configurations
Reference – Blog
13.1. Babelrc file
This file is placed under the root directory to set transcoding rules. For example, to use ES6 in your code, configure “presets”: [” ES2015 “] in this file. Plugins: [” transform-Runtime “, “transform-vue-jsx”]. Plugins: [“transform-runtime”, “transform-vue-jsx”]
13.2. Editorconfig file
This file configures the encoding style of the editor
EditorConfig Introduction – Blogs
13.3 .eslintrc
Reference – Blog
Configuration ESLint
ESLint can be configured in one of three ways:
- Use.eslintrc files (JSON and YAML syntax supported);
- Add an eslintConfig config block to package.json;
- Defined directly in the code file.
An example.eslintrc file:
{
"env": {
"browser": true,},"globals": {
"angular": true,},"rules": {
"camelcase": 2."curly": 2."brace-style": [2."1tbs"]."quotes": [2."single"]."semi": [2."always"]."space-in-brackets": [2."never"]."space-infix-ops": 2,}}Copy the code
In the project root directory, it will be applied to the entire project; If the subdirectory also contains an.eslintrc file, the subdirectory ignores the configuration file in the root directory and applies the configuration file in that directory. This makes it easy to apply different rules to code in different environments.
13.4. Eslintignore file
If you want to introduce tripartite JS libraries that do not conform to the ESLint specification, you can omit them in this file, for example:
build/*.js
config/*.js
static
Copy the code
13.5. Gitignore file
This file is used to configure files that do not need to be added to version management, for example:
.DS_Store
node_modules/
npm-debug.log
test/unit/coverage
test/e2e/reports
selenium-debug.log
.idea
/clear
/src/modules/cache.js
Copy the code
13.6 .browserslist
Reference – Blog
NPM address – official website
The configuration of the target browser and Node.js version is shared between different front-end tools.
Method of use
(1) Package. json (recommended)
{
"browserslist": [
"last 1 version"."1%" >."maintained node versions"."not dead"]}Copy the code
(2) .browserslistrc
# Browsers that we support
last 1 version
> 1%
maintained node versions
not dead
Copy the code
Browserslist’s data comes from Can I Use. You can use online Demo if you want to know the query result of configuration statement
13.7. Postcssrc. Js
Reference – Official website
It is one of many configuration methods
module.exports = {
"plugins": {
"postcss-import": {},
"postcss-url": {},
// to edit target browsers: use "browserslist" field in package.json
"autoprefixer": {}}}Copy the code
14. eslint
Reference – Chinese official website
15. Watch and watchOption
Reference – webpack
Watch mode is enabled by default in Webpack-dev-server and Webpack-dev-Middleware.
16. SplitChunksPlugin
See 1- Webpack – English
Reference 2- Blog – Chinese
The default configuration is our recommended Web best practice, but the optimal strategy for your project may vary depending on the type of project
By default, all modules from node_modules are assigned to the cache group called venders, and all modules referenced more than twice are assigned to the default cache group.