This is the 4th day of my participation in the August More Text Challenge
Preface 🛴
In the previous two articles, we covered the basics of WebPack. However, after the basic knowledge is understood, it must be applied to specific cases.
Therefore, in the following article, we will lead you to understand some actual case configuration of WebPack, including third-party library, PWA, TS packaging configuration, and advanced operation of WebpackDevServer, and also need to focus on mastering. How WebPack does performance optimization addresses this issue.
Here is the introduction of this article ~🚦
🚌 1. Library packaging
Suppose we want to develop a component library or a function library. How do we get WebPack to package such library code?
1. Webpack
Let’s say we’ve written a lot of logical code, and at the same time, we’ve packaged it, and it’s all generated in the mondaylib.js file in the dist folder.
Ok, now the library is generated. So how do we get our users to import mondaylib?
In general, other people introduce our library in the following ways:
/ / way
import mondaylib from 'mondaylib'
2 / / way
const mondaylib = require('mondaylib')
3 / / way
require(['mondaylib'].function(){})Copy the code
So, if we want our users to import the library, we need to configure it under webpack.config.js. The configuration is as follows:
const path = require('path');
module.exports = {
mode: 'production'.entry: './src/index.js'.output: {
path: path.resolve(__dirname, 'dist'),
filename: 'mondaylib.js'.// Set libraryTarget (umd) to commonJS
libraryTarget: 'umd'}}Copy the code
LibraryTarget: ‘umd’ indicates support for commonJS, so you can introduce the above three methods. LibraryTarget can also be set to other values, such as this and window.
LibraryTarget: ‘this’ means I’m going to mount the variable mondaylib to the page. LibraryTarget: ‘window’ is the variable mondaylib that will be mounted to the window.
In addition to the above three cases, there are other special cases, as follows:
<script src="mondaylib.js"></script>
Copy the code
At this point we need to do the following configuration in webpack.config.js:
const path = require('path');
module.exports = {
mode: 'production'.entry: './src/index.js'.output: {
path: path.resolve(__dirname, 'dist'),
filename: 'mondaylib.js'.// Mount the generated package code to the global variable of the page
library: 'mondaylib'.// Set libraryTarget (umd) to commonJS
libraryTarget: 'umd'}}Copy the code
Where the first library is the property value and the second mondaylib is our library name, this configuration means that the generated package code, the mondaylib.js library, is mounted to the global variable.
2. Library reference conflicts
So let’s say that now, in mondaylib above, we’ve introduced the loDash library. Then, when the user uses it, the user introduces the loDash library again. Like the following code:
import _ from 'lodash';
// Mondaylib has already introduced lodash
import mondaylib from 'mondaylib';
Copy the code
So now, how can we prevent this from happening? We will configure it in webpack.config.js, and the specific code is as follows:
const path = require('path');
module.exports = {
externals: ["lodash"]}Copy the code
Externals: [“lodash”] tells WebPack that if lodash is encountered in mondaylib during packaging, avoid it. In this way, you can effectively avoid the problem of multiple library references and reduce the package size of your code.
There is another special configuration for externals, as shown in the following code:
module.exports = {
externals: {
// Indicates that the loDash library, if used in commonJS, must be loaded as LoDash
lodash: {
commonjs: 'lodash'}}}Copy the code
If loDash is used in commonJS, it must be named LoDash when it is loaded. Something like this:
// Stocking Method: name it Lodash
import lodash from 'lodash'
- Unavailable mode: not named lodash
import _ from 'lodash'
Copy the code
🚍 2. PWA packaging configuration
1. What is PWA
PWA, or Progressive Web Application, stands for Progressive Web Application.
PWA is a relatively new front-end technology. What kind of technology is it?
What PWA can do is, if you go to a website, maybe the first time you go to a website, you get it, and then all of a sudden the website’s server dies. So this time you visit the site should be unable to access. However, the PWA caches the first page you visit. And then even if the server goes down, you can still display the page that you saw before.
Therefore, there is a plug-in in Webpack that can achieve this effect. Let’s have a look at ~
2. PWA in webpack
Step 1: Install the plug-in. The specific code is as follows:
npm install workbox-webpack-plugin --save-dev
Copy the code
Step 2: Import the plug-in in webpack.prod.js and use it. The specific code is as follows:
const WorkboxPlugin = require('workbox-webpack-plugin');
module.exports = {
plugins: [
new WorkboxPlugin.GenerateSW({
clientsClaim: true.skipWaiting: true}})],Copy the code
Normally, we only need to introduce PWA in the environment PROD online, and we don’t need to worry about this in the development environment. Through the above configuration, after the project is packaged, two new files will be generated in the dist directory, one is service-worker.js and the other is precache.
Step 3: Import the above files. The specific code is as follows:
if('serviceWorker' in navigator){
window.addEventListener('load'.() = > {
navigator.serviceWorker.register('/service-worker.js')
.then(registration= > {
console.log('service-worker registed');
}).catch(error= > {
console.log('service-worker regist error'); })})}Copy the code
We need to write a piece of business code in the entry file and introduce the service-worker.js file to help us do the PWA. At this point, we package the project, and then, if the server suddenly goes down, don’t worry, the PWA will load the original page for us to browse.
🚎 TypeScript packaging configuration
1. Cite examples
We all know that for different developers, different people write different styles of code, which makes it difficult to maintain the project at a later stage. So this is where Typescript, which has been all the rage in 2018, comes in. Ts standardizes a set of JS standards, so we can standardize our code through TS in the compilation of project code, and make the maintainability and scalability of our project become better.
Let’s take a look at how webPack configuration changes can be implemented to support TS syntax.
2. Webpack configuration for TS
(1) Background
Suppose we now have a section of ts code that needs to be compiled as follows:
class Greeter{
greeting: string;
constructor(message: string){
this.greeting = message;
}
greet(){
return "Hello, " + this.greeting; }}let greeter = new Greeter("world");
let button = document.createElement('button');
button.textContent = "Say Hello";
button.click = function(){
alert(greeter.greet());
}
document.body.appendChild(button);
Copy the code
Now, we want webPack to compile this TS code. What do we do?
(2) Configuration procedure
Step 1: Install ts-Loader. Specific commands are as follows:
npm install ts-loader typescript -D
Copy the code
Step 2: We configure it in the webpack.config.js file. The specific code is as follows:
const path = require('path');
module.exports = {
mode: 'production'.entry: './src/index.tsx'.module: {
rules: [{
test: /\.tsx? $/,
use: 'ts-loader'.exclude: /node_modules/}},output: {
filename: 'bundle.js'.path: path.resolve(__dirname, 'dist')}}Copy the code
Step 3: Configure the tsconfig.json file. The specific code is as follows:
{
"compilerOptions": {
"outDir": "./dist"."module": "es6"."target": "es5"."allowJs": true}}Copy the code
3. The TS identifies third-party libraries
Sometimes we call the Join method in LoDash, but if we don’t do anything special, we can import the loDash library into a TSX file and use it normally. Therefore, we need to install another TS library to do something about it. The specific steps are as follows:
Step 1: Install the @types/ LoDash library. Specific commands are as follows:
npm install @types/lodash --save-dev
Copy the code
Once the library is installed, TS can identify loDash functions and methods and report errors if they are referenced incorrectly.
Does TS have all the type files in this library (jQuery, etc.)?
The answer, of course, is no. We can go to the making of a url 👉 Microsoft. The dead simple. IO/TypeSearch/to search, if the search to get, then we can use @ type/library name for installation, after the TSX file will support type checking of the library.
🚕 4. Advanced operations of WebpackDevServer
1. WebpackDevServer implements request forwarding
Typically, you can set up a proxy server locally using the Charles Fiddler tool. Through this proxy server, we forward the address of the interface we want to request.
That gives us a tool in WebPack, devServer.proxy. Next, we configure in webpack.config.js as follows:
module.exports = {
devServer: {
proxy: {
'/react/api': {
target: 'http://www.mondaylab.com'.// Implement HTTPS url request forwarding
secure: false.bypass: function(req, res, proxyOptions){
// If the requested content is an HTML address, return the contents of index.html directly from the root path
if(req.headers.accept.indexOf('html')! = = -1) {console.log('Skipping proxy for browser request');
return './index.html';
// return false; // If an HTML request is received, what should be returned to you}},// Write header.json to the front end of the request, webpack will indirectly help us get demo.json data (request forwarding).
pathRewrite: {
'header.json': 'demo.json'
},
// If some sites are crawlproof, we may not be able to cross domains. You need to perform the following configuration to break the Origin restriction
changeOrigin: true.// Customize some content in the request header
headers: {
host: 'www.mondaylab.com'.// Simulate some operations such as login when forwarding requests
cookie: 'gfhgfh'
}
}
}
}
}
Copy the code
2. WebpackDevServer solves the problem of single page application routing
For modern mainstream frameworks, such as vue.js and react. js, they are mostly single-page applications. So, in a single page application, for example, we want to jump from http://mondaylab.com to http://mondaylab.com/list, how to jump?
This brings us to the routing of a single page application. We need to do the following configuration in webpack.config.js:
module.exports = {
devServer: {
// The first way
historyApiFallback: true./ * equivalent historyApiFallback: {rewrites: [{the from: / \ * \ /, to: '/ list. HTML /}]} * /
/* The second way to historyApiFallback: {rewrites: [{from: /abc.html/, // convert the list. '/list.html/' }] } */
HistoryApiFallback: {rewrites: [{// indicate that when a page is replaced, use the form of a function, combine some parameters of the context, and do some js logic in it to determine where it ends up. From: /^\/(libs)\/. function(context){ return '/bower_components' + context.match[0]; } }] } */}}Copy the code
It is important to note that historyApiFallback can only be used in development environments. If you go to the online environment, you need to ask the backend partner to go to Nginx or Apache, imitate some configurations of webpackDevServer, and do the same configuration on the backend server. After configuration, the front-end can use the corresponding route.
🚖 ESLint configuration in Webpack
1. What is ESLint
In our daily team development, everyone writes different kinds of code. Some people like to put a semicolon after code, and some people don’t. This grounding will easily lead to poor maintainability of our project. So, we introduced ESLint to constrain code specifications and make projects more maintainable and extensible.
How is ESLint configured in Webpack?
2. How to install ESLint
Step 1: Install the ESLint tool. Specific commands are as follows:
npm install eslint --save-dev
Copy the code
Step 2: Constrain our code. We need to create a new configuration file to configure our ESLint specification. Specific commands are as follows:
NPX eslint --init > Use a popular style guide Use a generic code check template > Airbnb > Do you Use React fill in y or n > Javascript > Would you like to install them now with npm? YCopy the code
Step 3: Use ESLint to examine code specifications. The specific code is as follows:
npx eslint src
Copy the code
The above code shows that esLint is used to detect code specifications in the SRC directory.
3. Why configure ESLint in Webpack
As we saw above, every developer can use the command line to check their code specifications, but if we had to run the command every time we wrote the code, it would be a bit troublesome to see if our code was properly written. At the same time, there is no guarantee that everyone’s ESLint code specification Settings will be the same.
Therefore, we can configure in WebPack to solve the above problems. The specific steps are as follows:
Step 1: Install eslint-Loader. The command lines are as follows:
npm install eslint-loader --save-dev
Copy the code
Step 2: Configure webpack.config.js. The specific code is as follows:
module.exports = {
devServer: {
/* When we run Webpack to do packaging, webPack will pop up an error layer in the browser to alert us to any specification problems in the code */
overlay: true
},
module: {
rules: [{
test: /\.js$/,
exclude: /node_modules/,
use: ['babel-loader'.'eslint-loader']]}}}Copy the code
With the basic configuration out of the way, let’s take a look at some other configurations for esLint-Loader. The specific code is as follows:
module.exports = {
module: {
rules: [{
test: /\.js$/,
exclude: /node_modules/,
use: ['babel-loader', {
loader: 'eslint-loader'.options: {
// Eslint-Loader will help us fix the code automatically if there are some fairly superficial problems
fix: true.// Reduce the cost of esLint on project performance during packaging
cache: true
},
// Force eslint-loader to run first
fore: 'pre'}}}}]]Copy the code
🏎️ 6. Webpack performance optimization
As you may have noticed, WebPack can sometimes be a little slow. This is grounded, and we’re gonna waste a lot of time we shouldn’t. So, here are some ways to speed up Webpack packaging.
1. Iterate with technology (Node,Npm,Yarn)
If we want to speed up the packaging of Webpack, we can upgrade the version of Webpack, or upgrade our Node, NPM manager, or YARN version.
So why does updating these tools speed up webPack packaging?
We think, Webpack in each version of the update, the internal will certainly do a lot of version optimization, therefore, when we do webpack version update, in the speed will certainly improve. The same is true for node, NPM, and YARN updates.
What’s the point of upgrading if it doesn’t? Isn’t it.
2. Apply Loader to as few modules as possible
In general, libraries of third-party modules are already packaged and compiled, so we need to ignore the node_module file when importing loader for compilation, or only use a loader in a folder to increase our packaging speed. We can configure it in webpack.config.js as follows:
module.exports = {
module: {
rules: [{
test: /\.js$/,
exclude: /node_modules/.// Or do the following ->include
//include: path.resolve(__dirname, '.. /src'),
use: [{
loader: 'babel-loader'}}}}]]Copy the code
Of course, according to the above idea, there are other loaders also have their corresponding precautions, which will not be elaborated here.
3. Use plug-ins wisely
Use plugins wisely. Don’t use redundant, meaningless plugins. At the same time, we should also choose those plug-ins with better performance and official approval to use, so that we can effectively improve the packaging speed of WebPack.
4. Set resolve properly
(1) Common configurations
Sometimes, we want to do some custom configuration for the files we import. What do we do? The configuration is as follows:
module.exports = {
resolve: {
extensions: ['js'.'jsx']./** * 1. When you import only one directory, such as import Child from './ Child/Child ', * WebPack does not know which file we want to import, * will look for the index file first. It will continue to find the child file */
mainFiles: ['index'.'child']./** * alias * For example, if you want to change the import method of a file to your own name * import Child from './Child' -> import Child from 'Monday' */
alias: {
monday: path.resolve(__dirname, '.. /src/Child'),}}}Copy the code
Next, the above parameters are explained in detail.
(2) Parameter explanation
1) extensions
- For example, when introducing
import Child from './child/child'
“, will first look for'./child/child.js'
Documents, if you can’t find them, look for them again'./child/child.jsx'
File. - Generally do not configure CSS and image files, because CSS and image may be a large number of times to perform the corresponding search. Indirectly, the effort to improve performance turns out to be wasted performance.
- So, if it’s like
css
和jpg
Such resource files should be explicitly imported; If it is likejs
和jsx
“, can be inextesions
For explicit import.
2) mainFiles
When you import only one directory, such as import Child from ‘./ Child/Child ‘, WebPack doesn’t know which file we are importing, so it looks for the index file first, and if it can’t find it, it continues to look for the Child file.
3) the alias
alias
As the name impliesThe alias. For example, you want to change the import method of a file to your own name–import Child from './Child' -> import Child from 'monday'
。- Often used in the case of multilevel directories.
5. Use the DllPlugin to speed up packaging
Sometimes we want to introduce third-party modules that are analyzed only the first time they are packaged and then not the next time they are packaged. So how do you deal with that?
Step 1: Create the webpack.dll.js file and configure it. The specific code is as follows:
const path = require('path');
const webpack = require('webpack');
module.exports = {
mode: 'production'.entry: {
// Fill in the name of the third party library that we want to package separately
vendors: ['react'.'react-dom'.'lodash']},output: {
filename: '[name].dll.js'.path: path.resolve(__dirname, '.. /dll'),
/* Use library to expose all the code in the third party module through global variables */
library: '[name]'
},
plugins: [
/* After the exposure is complete, the exposed module code is analyzed with the help of the DllPlugin to generate the manifest.json file */
new webpack.DllPlugin({
// Do DllPlugin analysis of the vendors libraries generated (file mapping)
name: '[name]'.// Analyze the path of the result, and then configure it in common.js with global variables
path: path.resolve(__dirname, '.. /dll/[name].manifest.json')]}})Copy the code
Step 2: Install the Add-asset-html-webpack-plugin. Specific commands are as follows:
npm install add-asset-html-webpack-plugin --save
Copy the code
Step 3: Configure the webpack.common.js file. The configuration is as follows:
const AddAssetHtmlWebpackPlugin = require('add-asset-html-webpack-plugin');
const webpack = require('webpack');
module.exports = {
entry: {
main: './src/index.js'.plugins: [
new HtmlWebpackPlugin({
template: 'src/index.html'
}),
/** * refers to adding something to the index.html generated by the HtmlWebpackPlugin */
new AddAssetHtmlWebpackPlugin({
filepath: path.resolve(__dirname, '.. /dll/vendors.dll.js')}),/** * 1. Use the DllReferencePlugin, * this plugin will go to '.. / DLL/vendors. The manifest. Json 'mapping relationship find third-party modules, * if the mapping relation can be found, then webpack will know that the third-party modules is not necessary to package came in again, * directly from the vendors in a DLL. Js can bring them here in the * 2. If it is not found in the mapping, then it will look for * */ in node_modules
new webpack.DllReferencePlugin({
manifest: path.resolve(__dirname, '.. /dll/vendors.manifest.json'})]}}Copy the code
Step 4: Configure the package.json file. The specific code is as follows:
{
"scripts": {
"build:dll": "webpack --config ./build/webpack.dll.js"}}Copy the code
Package the third-party libraries by running the NPM run build: DLL command.
6. Control the package file size
When we do project packaging, we should keep the generated files as small as possible. Sometimes when we are writing code, we often introduce some useless modules into the page, that is, introduce some modules that we use.
If you don’t configure tree-shaking, it’s easy to have a lot of redundant code when packaging. This redundant code, indirectly, slows down our Webpack speed.
So, when we do packaging, we have to control the size of the file. The specific steps are as follows:
- configuration
Tree-shaking
; - through
SplittingChunk
To split a large file into smaller files.
7. Multi-process packaging
Webpack runs through Node, so its packaging process is single-threaded. Sometimes, we can use multiple processes in Node to speed up the webpack process.
Common tools include Thread-loader, Parallel-Webpack, happypack and other tools. You can search for relevant information according to your own needs, select the most suitable tool for your project, and package it. I won’t go into detail on this one
8. Use sourceMap wisely
In general, the more detailed the sourceMap, the slower the packaging will be. So when we do packaging, we choose the most appropriate sourceMap configuration, depending on whether the current environment is development or production, to generate our corresponding code debug files.
This, on the one hand, ensures that we even find errors in the code. On the other hand, you can pack as fast as possible.
9. Analyze packaging results with STATS
When packaging the project, we can generate the stats file of the packaging status by command, and then analyze the packaging status in our packaging process by using some online or local packaging analysis tools.
For example, analyze which module takes a long time to package, which module takes a short time to package and analyze, etc., and optimize according to the specific situation.
10. In-memory compilation in the development environment
For compilation, webpackDevServer does not place the generated files in the dist directory. Instead, it places them in our computer’s memory.
11. Remove useless plug-ins from the development environment
For example, in the case of our development environment, we don’t need to compress the code. Therefore, the corresponding compression plug-in should not be configured in the development environment, only in the production environment. This way, you can reduce unnecessary packing time.
🏍️ 7. Multi-page packaging configuration
In general, whenever we do packaging, we do packaging for single-page applications. So what is a single page? There’s only one index.html file. Mainstream frameworks such as Vue and React are single-page applications. However, older frameworks like jquery and Zepto may require multi-page application packaging.
So, with that in mind, let’s talk about packaging configuration for multi-page applications in WebPack.
We can configure it in webpack.common.js with the following code:
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
// Import multiple entry files
main: './src/index.js'.list: './src/list.js'
},
plugins: [
new HtmlWebpackPlugin({
template: 'src/index.html'.filename: 'index.html'.//chunk indicates which files these HTML files are importing
chunks: ['runtime'.'vendors'.'main']}),new HtmlWebpackPlugin({
template: 'src/index.html'.filename: 'list.html'.chunks: ['runtime'.'vendors'.'list']]}})Copy the code
As can be seen from the above code, multiple entry pages can be added by adding the configuration of entry and plugins, thus achieving the effect of multi-page application configuration.
🛵 8. Conclusion
Through the above explanation, I believe that you have a certain understanding of the actual configuration of Webpack in some scenarios. The above is also relatively simple content, we can according to the corresponding knowledge points, broaden the scope of knowledge, in order to better apply to the actual project.
Here, on the webpack actual combat case configuration on the end of the explanation! Hope to help you ~
If the article is wrong or do not understand the place, welcome friends to leave a message in the comment section of 💬
This series of article code has been uploaded to the public account, background reply keyword webpack can be obtained ~
🐣 Egg One More Thing
Previous recommendation
- Webpack introductory basic knowledge 👉 10,000 words summary of webpack super introductory core knowledge
- Webpack entry advanced knowledge 👉 ten thousand words summary webpack actual case configuration
) Introduction
- Pay attention to the public number Monday laboratory, the first time to pay attention to quality articles, more selected columns for you to unlock ~
- If this article is useful to you, be sure to leave a footprint
- That’s all for this article! See you next time! 👋 👋 👋