How to use webpack
npm init -y npm install webapck webpack-cli --save-dev touch
Add content below
const path = require('path'); = { entry: './src/', output: { filename: '', path: (__dirname, 'dist') } };
- entry: The entrance to the project resource can be a single file or multiple files. Through each resource entry, webpack will look for its dependencies at one time for module packaging. We can understand entry as the root of the entire dependency tree, and each entry will correspond to a final generated packaging result.
- output: This is a configuration object through which we can configure the final packaged product. There are two properties configured here:
- path: The path force placed by packaged resources must be an absolute path.
- filename: The file name of the packaged result.
After defining the configuration file, use npx webpack or ./node_modules/.bin/webpack to execute
Using loader
A css file needs to be introduced into the project. If you directly use webpack to execute, an error will be reported. You need to add a loader mechanism to the webpack.
= { ... module: { rules: [ { // Use regular to match files ending with .css, and then use loader to convert test: /\.css$/, use: ['style-loader', 'css-loader'] } ] } }
Before compiling, you also need to install style-loader and css-loader
npm install --save-dev style-loader css-laoder
Notice:
The value of the use property is an array composed of the loader name. The order of loader execution is from behind to front. Since the loader execution is in order, it cannot be written like this.
use: ['css-loader', 'style-loader']
Each loader can pass parameters through the URL queryString, such as 'css-loader?url'
The principle of style-loader: it is to store the content of css using JavaScript strings, and dynamically insert HTML style tags into the HTML head tag when executing JavaScript on a web page through DOM operations.
The way to configure loader can also be implemented using Object
use: ['style-loader', { loader: 'css-loader', options: { url: true } }]
Using plugin
The function of loader is to convert certain types of modules, while plug-ins can be used to perform a wider range of tasks, ranging from packaging optimization and compression to redefining variables in the link.
If you want to use a plugin, we just need to require() and then add it to the plugins array. We can use a plugin multiple times in a configuration file for different purposes, so we can use the new operator to create its actual columns.
The above uses loader to load css into js. Now use the extract-text-webpack-plugin plugin to extract the css in the file to a separate file.
// Extract the plugin for cssconst ExtractTextPlugin = require('extract-text-webpack-plugin') module: { rules: [ { // Use regular to match files ending with .css, and then use loader to convert test: /\.css$/, loaders: ({ //Convert .css to loader use: ['css-loader'] }) } ] }, plugins: [ //The .css file name extracted from the js file new ExtractTextPlugin({ filename: '' }) ]
Before compiling, you need to install extract-text-webpack-plugin
npm install --save-dev extract-text-webpack-plugin
This is required to install it when executing webpack
npm install extract-text-webpack-plugin@next
DevServer
Official website
Install
npm install webpack-dev-server --save-dev
Then make a simple configuration
devServer:{ port: 3000, publicPath: "/dist" }
Then use./node_modules/.bin/webpack-dev-server
implement
Resource compression
npm i uglifyJSPlugin-webpack-plugin --save-dev
Configuration File
const UglifyJSPlugin = require('uglifyjs-webpack-plugin') plugins: [ new UglifyJSPlugin({ //The default is false and needs to be turned on manually parallel: true }) ]
or
optimization: { minimizer: [new UglifyJsPlugin()], },
Load on demand
At the code level, webpack supports two ways to load asynchronous modules, one is CommonJS form, and the other is ES6 Module form asynchronous import()
Asynchronously loaded scripts are not allowed to be used, so change the code to
export const log = function(){ (' loaded.') }
Edit, will be loaded in asynchronously
import('./').then(module =>{ () }).catch(error => "An error occurred while loading the module") (' loaded.')
Modify configuration
= { mode: "production", entry: './', output: { filename: '', path: (__dirname, 'dist'), publicPath: "./dist" }, }
Here we have added a configuration item publicPath to output. It is a very important configuration in webpack that is easy to confuse. When there are external resources such as on-demand loading and pictures and files in our project, it is necessary to configure the path of these resources. Otherwise, the page will report 404. Here we configure publicPath as a path relative to the html so that the on-demand loading resources are produced in the dist directory and can be referenced correctly.
After repackaging, you will find that there is one more package result, which is the content that will be loaded asynchronously in the future. Refresh the page and view the network tag of Chrome. You can see that the page will request it. It does not originate from references in it, but introduces it by inserting script tags into the page.
Build features using webpack
Starting from version 2.0.0, webpack has added more features that can optimize the build process.
tree-shaking
In the article about modules, we mentioned that the module dependency parsing of ES6 Module is performed during the static code analysis process. In other words, it can get a dependency tree during the compilation of the code, not the runtime. Using this, webpack provides tree-shaking function, which can help us detect which modules in the project have code that has never been referenced, which cannot be executed, so it is also called "dead code". Through tree-shaking, webpack can remove these dead codes during packaging to reduce the final resource volume.
It is very simple to enable the tree-shaking feature. Just make sure that the module follows the form definition of ES6 Module, which means that all our examples have actually been enabled by default. However, it should be noted that if babel-preset-es2015 or babel-preset-env is used in the configuration, the features of its module dependency resolution need to be turned off, such as:
presets: [ [env, {module: false}] ]
Here we test the function of tree-shaking, edit:
// export const log = function() { (' loaded.'); } export const unusedFunc = function() { ('not used'); }
Open the page to view the content, you should find that the unusedFunc code does not exist because it is not used by other modules and is a dead code and is optimized during the tree-shaking process.
The final effect of tree-shaking depends on the code of the actual project itself. In my test of actual project, the final volume can generally be reduced by 3% to 5%. Overall, I think it will take several years to make tree-shaking work, because most npm modules are still using CommonJS, so I can't enjoy the advantages brought by this feature.
scope-hoisting
scope-hoisting is a feature provided by webpack3. In large projects, module reference levels are often deeper, which will produce longer reference chains. scope-hoisting can flatten this depth of reference chain so that the module itself is at the same level as the other modules it references. In this way, some additional code of webpack can be removed, the resource volume can be reduced, and the code execution efficiency can be improved.
Currently, if you want to enable scope-hoisting, you need to introduce an internal plug-in of it:
= { plugins: [ new () ] }
After scope-hoisting takes effect, you will see something like the following in it. You will find that the definition and call of the log are in the same scope:
// CONCATENATED MODULE: ./ const log = function() { (' loaded.'); } // CONCATENATED MODULE: ./ log();
The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.