[[webpack官方网站](https://webpack.js.org/)]
**webpack** is a *static module bundler* for modern JavaScript applications. Webpack is used to compile JavaScript modules. Once installed, you can interface with webpack either from its `CLI` or `API`.
An implementation of ES6 is free to do all the work at compile time and bundle all your modules into a single file to ship them over the network! And tools like [webpack](http://www.2ality.com/2015/04/webpack-es6.html) actually do this.
[![webpack shield](https://img.shields.io/npm/v/webpack.svg?label=webpack&style=flat-square&maxAge=3600)](https://github.com/webpack/webpack/releases)
webpack is a module bundler. Its main purpose is to bundle JavaScript files for usage in a browser, yet it is also capable of transforming, bundling, or packaging just about any resource or asset.
Bundlers help you get your JavaScript and stylesheets ready for deployment, transforming them into a format that's suitable for the browser. For example, JavaScript can be [minified](https://webpack.js.org/plugins/terser-webpack-plugin) or [split into chunks](https://webpack.js.org/guides/code-splitting) and [lazy-loaded](https://webpack.js.org/guides/lazy-loading) to improve performance. Bundling is one of the most important challenges in web development, and solving it well can remove a lot of pain from the process.
---
**目录**
[TOC]
---
## Core Concepts
[[webpack官方网站 concepts](https://webpack.js.org/concepts/)]
### Entry
[[webpack官方网站 Entry]](https://webpack.js.org/concepts/#entry)
### Output
[[webpack官方网站 Output]](https://webpack.js.org/concepts/#output)
### Loaders
[[webpack官方网站 Loaders]](https://webpack.js.org/concepts/#loaders)
### Plugins
[[webpack官方网站 Plugins]](https://webpack.js.org/concepts/#plugins)
### Mode
[[webpack官方网站 Mode]](https://webpack.js.org/concepts/#mode)
### Browser Compatibility
[[webpack官方网站 Browser Compatibility]](https://webpack.js.org/concepts/#browser-compatibility)
## Development
[[webpack官方网站 Development]](https://webpack.js.org/guides/development/)
### 4 methodes to watch effect after source code files had been modified
1. `npm run build`
2. `npm run watch`
3. `npm start`
4. `npm run server`
* **package.json**
~~~
{
"name": "webpack-demo",
"version": "1.0.0",
"description": "",
"private": true,
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
//npm run build,dependency:webpack, 生成目标文件
"build": "webpack",
//npm run watch,dependency:webpack --watch,
//webpack's Watch Mode: 监视源文件的变化,有变化就编译到目标文件
"watch": "webpack --watch",
//npm start,dependency:webpack-dev-server
// webpack-dev-server, 默认localhost:8080,启动服务器端显示源文件编译后的实际情况
"start": "webpack-dev-server --open",
//npm run server,dependency:webpack-dev-middleware
// webpack-dev-middleware, 要设置localhost:???,还要写server.js;启动服务器端显示源文件编译后的实际情况,源文件有变化需手动刷新。
"server": "node server.js"
},
"keywords": [],
"author": "",
"license": "ISC",
//npm install --save-dev XX,应用 npm install 命令进行安装的插件和依赖
"devDependencies": {
"clean-webpack-plugin": "^3.0.0",
"css-loader": "^3.0.0",
"csv-loader": "^3.0.2",
"express": "^4.17.1",
"file-loader": "^4.0.0",
"html-webpack-plugin": "^3.2.0",
"lodash": "^4.17.11",
"style-loader": "^0.23.1",
"webpack": "^4.35.0",
"webpack-cli": "^3.3.4",
"webpack-dev-middleware": "^3.7.0",
"webpack-dev-server": "^3.7.2",
"xml-loader": "^1.2.1"
}
}
~~~
* **webpack.config.js**
~~~ javascript
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
mode:'development',
entry:{
app:'./src/index.js',
print:'./src/print.js'
},
devtool:'inline-source-map',
devServer:{
contentBase:'./dist'
},
plugins:[
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
title:'Development'
})
],
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist'),
publicPath:'/'
}
};
~~~
>[info] `webpack-dev-server` doesn't write any output files after compiling. Instead, it keeps bundle files in memory and serves them as if they were real files mounted at the server's root path. If your page expects to find the bundle files in different path, you can change this with the[`publicPath`](https://webpack.js.org/configuration/dev-server/#devserver-publicpath-)option in the dev server's configuration.
### Hot Module Replacement(HMR)
Hot Module Replacement (or HMR) is one of the most useful features offered by webpack. It allows all kinds of modules to be updated at runtime without the need for a full refresh.
>[warning] **HMR** is not intended for use in production, meaning it should only be used in development. See the [building for production guide](https://webpack.js.org/guides/production) for more information.
* Enabling HMR
* Via the Node.js API
### Output Management
1. `HtmlWebpackPlugin`: by default it will generate its own `index.html` file.
First install the plugin
~~~ bash
npm install --save-dev html-webpack-plugin
~~~
then, adjust the`webpack.config.js`file:
**webpack.config.js**
~~~diff
const path = require('path');
+ const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
app: './src/index.js',
print: './src/print.js'
},
+ plugins: [
+ new HtmlWebpackPlugin({
+ title: 'Output Management'
+ })
+ ],
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist')
}
};
~~~
learn more about all the features and options that the`HtmlWebpackPlugin`provides, then you should read up on it on the[`HtmlWebpackPlugin`](https://github.com/jantimon/html-webpack-plugin)repo.
2. `clean-webpack-plugin`: clean the`/dist`folder before each build,
[[官方文档 `clean-webpack-plugin`]](https://www.npmjs.com/package/clean-webpack-plugin)
First install the plugin
~~~ bash
npm install --save-dev clean-webpack-plugin
~~~
then, adjust the`webpack.config.js`file:
**webpack.config.js**
~~~diff
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
+ const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
entry: {
app: './src/index.js',
print: './src/print.js'
},
plugins: [
+ new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
title: 'Output Management'
})
],
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist')
}
};
~~~
3. `WebpackManifestPlugin`: The manifest data can be extracted into a json file for easy consumption.
[[官方文档`WebpackManifestPlugin`]](https://github.com/danethurber/webpack-manifest-plugin).
### Code Splitting
Webpack allows you to split your codebase into multiple chunks. Chunks are loaded asynchronously at runtime. This reduces the initial loading time.
Code splitting is one of the most compelling features of webpack. This feature allows you to split your code into various **bundles which can then be loaded on demand or in parallel**. It can be used to achieve smaller bundles and control resource load prioritization which, if used correctly, can have a major impact on load time.
There are three general approaches to code splitting available:
* Entry Points: Manually split code using [`entry`](https://webpack.js.org/configuration/entry-context)configuration.
* Prevent Duplication: Use the [`SplitChunksPlugin`](https://webpack.js.org/plugins/split-chunks-plugin/)to dedupe and split chunks.
* Dynamic Imports: Split code via inline function calls within modules.
`SplitChunksPlugin`: to extract common dependencies into an existing entry chunk or an entirely new chunk.
>[warning] The`CommonsChunkPlugin`has been removed in webpack v4 legato. To learn how chunks are treated in the latest version, check out the [`SplitChunksPlugin`](https://webpack.js.org/plugins/split-chunks-plugin/).
**webpack.config.js**
~~~diff
const path = require('path');
module.exports = {
mode: 'development',
entry: {
index: './src/index.js',
another: './src/another-module.js'
},
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist')
},
+ optimization: {
+ splitChunks: {
+ chunks: 'all'
+ }
+ }
};
~~~
>[info] `optimization`: webpack can do many optimizations to **reduce the output size of your JavaScript** by deduplicating frequently used modules, minifying, and giving you full control of what is loaded initially and what is loaded at runtime through code splitting. It can also make your code chunks **cache friendly** by using hashes.
Here are some other useful plugins and loaders provided by the community for splitting code:
* [`mini-css-extract-plugin`](https://webpack.js.org/plugins/mini-css-extract-plugin): Useful for splitting CSS out from the main application.
* [`bundle-loader`](https://webpack.js.org/loaders/bundle-loader): Used to split code and lazy load the resulting bundles.
* [`promise-loader`](https://github.com/gaearon/promise-loader): Similar to the`bundle-loader`but uses promises.
### Dynamic Imports
`import()` syntax: (recommended approach) conforms to the [ECMAScript proposal](https://github.com/tc39/proposal-dynamic-import) for dynamic imports.
>[warning] `import()`calls use [promises](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) internally. If you use`import()`with older browsers, remember to shim`Promise`using a polyfill such as [es6-promise](https://github.com/stefanpenner/es6-promise) or [promise-polyfill](https://github.com/taylorhakes/promise-polyfill).
As`import()`returns a promise, it can be used with[`async`functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function). However, this requires using a pre-processor like Babel and the [Syntax Dynamic Import Babel Plugin](https://babeljs.io/docs/plugins/syntax-dynamic-import/#installation). Here's how it would simplify the code:
**src/index.js**
~~~javascript
async function getComponent() {
const element = document.createElement('div');
const { default: _} = await import(/* webpackChunkName: "lodash" */ 'lodash');
element.innerHTML = _.join(['Hello', 'webpack'], ' ');
return element;
}
getComponent().then( com =>{
document.body.appendChild(com);
});
~~~
The reason we need`default`is that since webpack 4, when importing a CommonJS module (`lodash`), the `import` will no longer resolve to the value of`module.exports`, it will instead create an artificial namespace object for the CommonJS module. For more information on the reason behind this, read [webpack 4: import() and CommonJs](https://medium.com/webpack/webpack-4-import-and-commonjs-d619d626b655).
Note the use of `webpackChunkName` in the comment. This will cause our separate bundle to be named `lodash.bundle.js` instead of just `[id].bundle.js`. For more information on `webpackChunkName` and the other available options, see the[`import()`documentation](https://webpack.js.org/api/module-methods#import-). Let's run webpack to see`lodash`separated out to a separate bundle:
~~~bash
...
Asset Size Chunks Chunk Names
index.bundle.js 7.88 KiB index [emitted] index
vendors~lodash.bundle.js 547 KiB vendors~lodash [emitted] vendors~lodash
Entrypoint index = index.bundle.js
...
~~~
### Prefetching/Preloading modules ??
### Bundle Analysis ??
Once you start splitting your code, it can be useful to analyze the output to check where modules have ended up. The [official analyze tool](https://github.com/webpack/analyse)is a good place to start. There are some other community-supported options out there as well:
* [webpack-chart](https://alexkuz.github.io/webpack-chart/): Interactive pie chart for webpack stats.
* [webpack-visualizer](https://chrisbateman.github.io/webpack-visualizer/): Visualize and analyze your bundles to see which modules are taking up space and which might be duplicates.
* [webpack-bundle-analyzer](https://github.com/webpack-contrib/webpack-bundle-analyzer): A plugin and CLI utility that represents bundle content as a convenient interactive zoomable treemap.
* [webpack bundle optimize helper](https://webpack.jakoblind.no/optimize): This tool will analyze your bundle and give you actionable suggestions on what to improve to reduce your bundle size.
### Lazy Loading
Lazy, or "on demand", loading is a great way to optimize your site or application. This speeds up the initial load of the application and lightens its overall weight as some blocks may never even be loaded.
Many frameworks and libraries have their own recommendations on how this should be accomplished within their methodologies. Here are a few examples:
* React:[Code Splitting and Lazy Loading](https://reacttraining.com/react-router/web/guides/code-splitting)
* Vue:[Lazy Load in Vue using Webpack's code splitting](https://alexjoverm.github.io/2017/07/16/Lazy-load-in-Vue-using-Webpack-s-code-splitting/)
* Angular:[Lazy Loading route configuration](https://angular.io/guide/router#milestone-6-asynchronous-routing)
* AngularJS:[AngularJS + Webpack = lazyLoad](https://medium.com/@var_bin/angularjs-webpack-lazyload-bb7977f390dd)by[@var\_bincom](https://twitter.com/var_bincom)
### Caching
the configuration needed to ensure files produced by webpack compilation can remain cached unless their content has changed.
We can use the `output.filename`[substitutions](https://webpack.js.org/configuration/output#output-filename) setting to define the names of our output files. webpack provides a method of templating the filenames using bracketed strings called **substitutions**. The `[contenthash]` substitution will add a unique hash based on the content of an asset. When the asset's content changes, `[contenthash]` will change as well.
**webpack.config.js**
~~~diff
const path = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.js',
plugins: [
// new CleanWebpackPlugin(['dist/*']) for < v2 versions of CleanWebpackPlugin
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
title: 'Caching'
})
],
output: {
- filename: 'bundle.js',
+ filename: '[name].[contenthash].js',
path: path.resolve(__dirname, 'dist')
}
};
~~~
Running our build script,`npm run build`, with this configuration should produce the following output:
~~~bash
...
Asset Size Chunks Chunk Names
main.7e2c49a622975ebd9b7e.js 544 kB 0 [emitted] [big] main
index.html 197 bytes [emitted]
...
~~~
As you can see the bundle's name now reflects its content (via the hash). If we run another build without making any changes, we'd expect that filename to stay the same.
**Extracting Boilerplate**
Webpack provides an optimization feature to split runtime code into a separate chunk using the [`optimization.runtimeChunk`](https://webpack.js.org/configuration/optimization/#optimization-runtimechunk) option. Set it to `single` to create a single runtime bundle for all chunks.
Webpack provides `optimization.splitChunks` with `cacheGroups` to extract third-party libraries, such as `lodash` or `react`, to a separate `vendor` chunk as they are less likely to change than our local source code.This step will allow clients to request even less from the server to stay up to date.
**webpack.config.js**
~~~diff
const path = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.js',
plugins: [
// new CleanWebpackPlugin(['dist/*']) for < v2 versions of CleanWebpackPlugin
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
title: 'Caching'
}),
],
output: {
filename: '[name].[contenthash].js',
path: path.resolve(__dirname, 'dist')
},
optimization: {
runtimeChunk: 'single',
+ splitChunks: {
+ cacheGroups: {
+ vendor: {
+ test: /[\\/]node_modules[\\/]/,
+ name: 'vendors',
+ chunks: 'all'
+ }
+ }
+ }
}
};
~~~
Let's run another build to see our new`vendor`bundle:
~~~bash
...
Asset Size Chunks Chunk Names
runtime.cc17ae2a94ec771e9221.js 1.42 KiB 0 [emitted] runtime
vendors.a42c3ca0d742766d7a28.js 69.4 KiB 1 [emitted] vendors
main.abf44fedb7d11d4312d7.js 240 bytes 2 [emitted] main
index.html 353 bytes [emitted]
...
~~~
We can now see that our`main`bundle does not contain `vendor` code from `node_modules` directory and is down in size to `240 bytes`!
**Module Identifiers**
`NamedModulesPlugin`: it will uses the path to the module rather than a numerical identifier. While this plugin is useful during development for more readable output, it does take a bit longer to run.
[`HashedModuleIdsPlugin`](https://webpack.js.org/plugins/hashed-module-ids-plugin): recommended for production builds:
**webpack.config.js**
~~~diff
+ const webpack = require('webpack');
module.exports = {
plugins: [
+ new webpack.HashedModuleIdsPlugin()
],
};
~~~
### Authoring Libraries ??
[[webpack官方网站 author-libraries]](https://webpack.js.org/guides/author-libraries/)
Aside from applications, webpack can also be used to bundle JavaScript libraries.
You can [publish it as an npm package](https://docs.npmjs.com/getting-started/publishing-npm-packages) and find it at [unpkg.com](https://unpkg.com/#/) to distribute it to your users.
### Environment Variables
[[webpack官方网站 environment-variables]](https://webpack.js.org/guides/environment-variables/)
### Module
[[webpack官方网站-Module](https://webpack.js.org/concepts/modules/)]
In contrast to [Node.js modules](https://nodejs.org/api/modules.html), webpack *modules* can express their *dependencies* in a variety of ways. A few examples are:
* An [ES2015 `import`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import) statement
* A [CommonJS](http://www.commonjs.org/specs/modules/1.0/) `require()` statement
* An [AMD](https://github.com/amdjs/amdjs-api/blob/master/AMD.md) `define` and `require` statement
* An [`@import` statement](https://developer.mozilla.org/en-US/docs/Web/CSS/@import) inside of a css/sass/less file.
* An image url in a stylesheet (`url(...)`) or html (`<img src=...>`) file.
>[info] webpack 1 requires a specific loader to convert ES2015 `import`, however this is possible out of the box via webpack 2
#### Supported Module Types
webpack supports modules written in a variety of languages and preprocessors, via *loaders*. *Loaders* describe to webpack **how** to process non-JavaScript *modules* and include these *dependencies* into your *bundles*. The webpack community has built *loaders* for a wide variety of popular languages and language processors, including:
* [CoffeeScript](http://coffeescript.org)
* [TypeScript](https://www.typescriptlang.org)
* [ESNext (Babel)](https://babeljs.io)
* [Sass](http://sass-lang.com)
* [Less](http://lesscss.org)
* [Stylus](http://stylus-lang.com)
And many others! Overall, webpack provides a powerful and rich API for customization that allows one to use webpack for **any stack**, while staying **non-opinionated** about your development, testing, and production workflows.
module.export
loader
import/require
## Production
[[webpack官方网站 Production]](https://webpack.js.org/guides/production/)
## Tree Shaking
[[webpack官方网站 Tree-shaking]](https://webpack.js.org/guides/tree-shaking/)
**Tree shaking** is a term commonly used in the JavaScript context for dead-code elimination. It relies on the [static structure](http://exploringjs.com/es6/ch_modules.html#static-module-structure) of ES2015 module syntax, i.e. `import` and `export`.
in order to take advantage of `tree shaking`, you must...
* Use ES2015 module syntax (i.e.`import`and`export`).
* Ensure no compilers transform your ES2015 module syntax into CommonJS modules (this is the default behavior of popular Babel preset @babel/preset-env - see [documentation](https://babeljs.io/docs/en/babel-preset-env#modules) for more details).
* Add a `"sideEffects"` property to your project's `package.json` file.
* Use `production` `mode`configuration option to enable various `optimizations` including minification and tree shaking.
You can imagine your application as a tree. The source code and libraries you actually use represent the green, living leaves of the tree. Dead code represents the brown, dead leaves of the tree that are consumed by autumn. In order to get rid of the dead leaves, you have to shake the tree, causing them to fall.
## 待求证
1. [设置webpack,在JS文件中使用es6的语法](https://blog.csdn.net/a250758092/article/details/78543440)
- WebAPP
- Linux Command
- 入门
- 处理文件
- 查找文件单词
- 环境
- 联网
- Linux
- Linux目录配置标准:FHS
- Linux文件与目录管理
- Linux账号管理与ACL权限设置
- Linux系统资源查看
- 软件包管理
- Bash
- Daemon/Systemd
- ftp
- Apache
- MySQL
- Command
- Replication
- mysqld
- remote access
- remark
- 限制
- PHP
- String
- Array
- Function
- Class
- File
- JAVA
- Protocals
- http
- mqtt
- IDE
- phpDesigner
- eclipse
- vscode
- Notepad++
- WebAPI
- Javasript
- DOM
- BOM
- Event
- Class
- Module
- Ajax
- Fetch
- Promise
- async/await
- Statements and declarations
- Function
- Framwork
- jQurey
- Types
- Promise
- BootStrap
- v4
- ThinkPHP5
- install
- 定时任务
- CodeIgniter
- React.js
- node.js
- npm
- npm-commands
- npm-folder
- package.json
- Docker and private modules
- module
- webpack.js
- install
- configuration
- package.json
- entry
- modules
- plugins
- Code Splitting
- loaders
- libs
- API
- webpack-cli
- Vue.js
- install
- Compile
- VueAPI
- vuex
- vue-router
- vue-devtools
- vue-cli
- vue-loader
- VDOM
- vue-instance
- components
- template
- Single-File Components
- props
- data
- methods
- computed
- watch
- Event-handling
- Render Func
- remark
- 案例学习
- bootstrap-vue
- modal
- fontAwesome
- Hosting Font Awesome Yourself
- using with jquery
- using with Vue.js
- HTML
- CSS
- plugins
- Chart.js
- D3.js
- phpSpreadSheet
- Guzzle
- Cmder
- Git
- git命令
- git流程
- Postman
- Markdown
- Regular Expressions
- PowerDesigner
- 附录1-学习资源