Webpack learning notes series 04 - resource processing optimization

CS Xiaoyao Sword Fairy 2021-02-23 03:37:59
webpack learning notes series resource


webpack Learning notes series 04- Resource processing optimization

Write By CS Xiaoyao sword immortal My home page : csxiaoyao.com GitHub: github.com/csxiaoyaojianxian Email: sunjianfeng@csxiaoyao.com QQ: 1724338257

1. To configure typescript

1.1 tsconfig.json

newly build ts file :

// hello.ts
function sayHello(name: string) {
return 'Hello, ' + name;
}
let name = 'csxiaoyao';
console.log(sayHello(name));

Install it directly on the command line ts And compile :

$ npm i -g typescript
# Compiled into hello.js
$ tsc hello.ts

Compiled file :

function sayHello(name) {
return 'Hello, ' + name;
}
var name = 'csxiaoyao';
console.log(sayHello(name));

TypeScript Yes tsconfig.json File to store project configuration , Document links .

{
"compilerOptions": {
"outFile": "dist/main.js",
"sourceMap": true
},
"files": ["src/index.ts", "src/source.ts"]
}

If you use tsconfig.json file , Just execute tsc that will do .

$ tsc

1.2 webpack Integrate typescript

install ts-loader:

$ npm i ts-loader --save-dev

To configure webpack.config.js

module.exports = {
entry: './src/app.ts',
output: {
filename: 'app.js',
path: './dist'
},
resolve: {
extensions: ['', '.webpack.js', '.web.js', '.ts', '.js']
},
module: {
loaders: [
{
test: /\.ts$/,
loader: 'ts-loader'
}
]
}
};

Cooperate with the project root directory tsconfig.json File to achieve ts Integration of .

2. css Handle

2.1 css-loader

webpack Everything in is modular ,css Documents can be found in JavaScript Is directly quoted in , But it can't be resolved css grammar ,css-loader Be able to make css Convert to string for js Use .

$ npm i -D css-loader

add to rule:

{
module: {
rules: [
{
test: /\.css$/,
use: ['css-loader']
}
]
}
}

Or use inline writing directly :

import css from 'css-loader!./css/index.css';
console.log(css);

2.2 style-loader

style-loader Yes, it will css-loader Packed CSS Code to <style> The form of the label is inserted into HTML In file , therefore style-loader Is in css-loader Then it comes in pairs .

$ npm i -D style-loader

add to rule:

module: {
rules: [
{
test: /\.css$$/,
use: ['style-loader', 'css-loader']
}
]
}

Or use inline writing directly :

import css from 'style-loader!css-loader!./css/index.css';
console.log(css);

2.3 mini-css-extract-plugin

Will be css With <style> The form of the label is inserted into HTML Based on the document , Also need to css With <link> In the form of a label URL introduce , At this time, we need to use mini-css-extract-plugin This plugin .

$ npm install --save-dev mini-css-extract-plugin

The configuration file needs to be modified at the same time loader and plugin,loader Need to put in css-loader Then replace style-loader:

const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
plugins: [
// add to plugin
new MiniCssExtractPlugin({
filename: '[name].css',
chunkFilename: '[id].css'
})
],
module: {
rules: [
{
test: /\.css$/,
// add to loader
use: [MiniCssExtractPlugin.loader, 'css-loader']
}
]
}
};

2.4 CSS Modules

Compiler tools can implement css The modular , Reference resources css-loader.

Come on , You need to use mini-css-extract-plugin This plug-in , First install it :

{
module: {
rules: [
{
test: /\.css$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
modules: true
}
}
]
}
]
}
}

After packaging class Will be replaced to achieve modularity .

2.5 CSS The preprocessor

Common preprocessors are :less、sass(scss)、stylus, Here to less For example .

$ npm i -D less-loader

modify webpack To configure :

// webpack.config.js
module.exports = {
module: {
rules: [{
test: /\.less$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
modules: true
}
},
'less-loader' // take less Compiled into css
]
}]
}
};

2.6 CSS Post processor PostCSS

2.6.1 PostCSS

PostCSS It's a use JavaScript Plug in to convert css Tools for , Not only can we deal with CSS And preprocessor Syntax , It can also handle adding prefixes 、 The latest grammatical escape 、 Compress 、 Even expand CSS The language characteristics of English . Its realization is related to babel similar , take CSS It can be interpreted as AST And then transform to create a new CSS.PostCSS It can make css It's easier to write , If you use it according to the appropriate browser Autoprefixer Plug ins automatically add prefixes to fit different browsers .

/* index.css */
.flex {
display: flex;
}
/* the postcss autoprefixer After processing */
.flex {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
}

2.6.2 postcss-loader

install postcss-loader:

$ npm i -D postcss-loader

modify webpack.config.js,postcss-loader Need to be in css-loader Or preprocessor loader Before .

module.exports = {
module: {
rules: [
{
test: /\.less$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
modules: true,
importLoader: 2
}
},
'less-loader',
'postcss-loader'
]
}
]
}
};

2.6.3 postcss To configure

PostCSS It's just that CSS It can be interpreted as AST, We need to rely on its powerful plug-in system to achieve rich functions , There are three ways to write configuration :

  1. The configuration file in the root directory of the project postcss.config.js
  2. webpack The configuration file corresponds to loader Configuration item for options
  3. Directly in package.json Add postcss attribute

The way 1: postcss.config.js

// postcss.config.js
const autoprefixer = require('autoprefixer');
module.exports = {
plugins: [autoprefixer(['IE 10'])]
};

The way 2: loader Configuration item options

// introduce postcss plug-in unit
const autoprefixer = require('autoprefixer');
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: [
'style-loader',
'css-loader',
{
loader: 'postcss-loader',
options: {
// plugins Options
plugins: [autoprefixer(['IE 10'])]
}
}
]
}
]
}
};

The way 3: package.json Add postcss attribute

Limited by json grammar , Less scalable , Not recommended .

{
"postcss": {
"plugins": {
"autoprefixer": "IE 10"
}
}
}

2.6.4 Commonly used postcss plug-in unit

autoprefixer

The main parameter is browserslist, For giving css Complete all kinds of browser private prefixes , Such as -webkit、-moz 、-ms etc. , It also deals with various compatibility issues , Such as flex Processing into -webkit-box etc. .

postcss-preset-env

And babel Of preset-env similar , You can use the latest css Grammar to write style , Such as cssnext etc. .

PreCSS

You can write classes sass and cssnext The grammatical CSS.

cssnano

according to CSS Syntax parsing results intelligent compression code , For example, merge some class writing 、 Shorten the color value and other common values .

postcss-import

Support handling @import Introduced CSS Code , Effects and settings css-loader Of importLoaders identical .

importLoaders Express css-loader Act on @import How many resources before loader Value : 0 => Default , No, loader 1 => postcss-loader 2 => postcss-loader, sass-loader

// Use it directly postcss-import plug-in unit
const autoprefixer = require('autoprefixer');
const postcssImport = require('postcss-import');
module.exports = {
plugins: [postcssImport(), autoprefixer(['IE 10'])]
};

2.7 css Compression processing

cssnano Is based on postcss The plug-in package , Integrated 30 Various plug-ins , Be able to optimize in many ways , Such as :

  • Remove the space and the last semicolon
  • Delete Note
  • Optimize font weight
  • Discard duplicate style rules
  • Compression selector
  • Reduce handwriting attributes
  • Merger rules
// webpack.config.js
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
module.exports = {
plugins: [
new OptimizeCssAssetsPlugin({
assetNameRegExp: /\.optimize\.css$/g,
cssProcessor: require('cssnano'), // Specify the engine , Default cssnano
cssProcessorPluginOptions: {
preset: ['default', {discardComments: {removeAll: true}}]
},
canPrint: true
})
]
};

stay CSS Recommended in contenthash A place holder is a file hash Algorithm .

3. lint Tools deal with code style quality

3.1 ESLint

ESLint By configuring rules (Rules) To detect JavaScript Grammatical norms , Well known configuration rules in the industry are :Airbnb、Standard、Google etc. , Used in projects :

# install CLI Tools
$ npm install -D eslint
# create profile .eslintrc.json
$ eslint --init
# Operation inspection
$ npx eslint

Generated .eslintrc.json The configuration file is as follows :

{
"env": {
"browser": true,
"es6": true
},
"extends": "airbnb-base",
"globals": {
"Atomics": "readonly",
"SharedArrayBuffer": "readonly"
},
"parserOptions": {
"ecmaVersion": 2018,
"sourceType": "module"
},
"rules": {}
}

If you want to use the general rules of the industry directly , You need to install the rules first :

# airbnb
$ npm install --save-dev eslint-config-airbnb
# google
$ npm install --save-dev eslint-config-google
# standard
$ npm install --save-dev eslint-config-standard

And then in .eslintrc.json Modify... In configuration file extends Is the corresponding value :

{
"extends": "standard",
"rules": {}
}

To customize some extra rules , You can configure the rules,ESLint There are three types of error reports :off (0)、warn (1)、error (2).

{
'rules': {
// prohibit console
'no-console': 2,
// prohibit debugger
'no-debugger': 2,
// prohibit alert
'no-alert': 2,
// left-off var, To delete , Manual tree shaking
'no-unused-vars': 2,
// Undefined cannot be used , I want to write eslint global
'no-undef': 2
}
}

3.2 webpack Use eslint

install eslint-loader:

npm install -D eslint-loader

To configure rule:

{
test: /\.js$/,
loader: 'eslint-loader',
enforce: 'pre', // Manual adjustment loader Loading order , Make sure you check the code style first , Do it again babel Conversion, etc
include: [path.resolve(__dirname, 'src')], // Specify the directory to check
options: { // The configuration item parameters here will be passed to eslint Of CLIEngine
formatter: require('eslint-formatter-friendly') // Specify the format specification for the error report , Additional installation required
}
}

Be careful :

  1. Whether as an independent module.rule To configure , Or put it in babel Of rule in , Make sure you pass first eslint-loader Check code style
  2. TypeScript Need to use tslint-loader To test

JavaScript Code specification , countries

3.3 StyleLint

Used to detect css grammar , What are the official recommended rules :stylelint-config-recommended and stylelint-config-standard.

$ npm install -D stylelint

Besides , Through installation stylelint-order Plug ins can be standardized css Writing order , Write positioning first , Write the box model again , Write the content area style again , Last write CSS3 Related properties .

StyleLint The configuration file is .stylelintrc.json, Writing and ESLint Configuration is similar to :

{
"extends": ["stylelint-config-standard", "stylelint-config-recess-order"],
"rules": {
// Support SCSS The grammatical mixin、extend、content grammar
"at-rule-no-unknown": [true, {"ignoreAtRules": ["mixin", "extend", "content"]}]
}
}

3.4 webpack Use stylelint

adopt stylelint-webpack-plugin Plug in to use .

$ npm install -D stylelint-webpack-plugin

Modify the configuration , You can configure the emitErrors and failOnError Parameters .

const StyleLintPlugin = require('stylelint-webpack-plugin');
module.exports = {
plugins: [new StyleLintPlugin(options)]
};

By default, the plug-in looks for .stylelintrc.json The configuration file .

4. Static resource processing

4.1 Use file-loader / url-loader Load image resources

file-loader and url-loader They are the two most commonly used to process image resources loader, And they can replace each other in certain application scenarios .

file-loader: Copy the used resources according to the configuration items ( Not limited to pictures ) To the built folder , And change the corresponding link

url-loader: contain file-loader All functions , And can be converted to Base64 Mode introduction

With url-loader For example , First installation :

$ npm install -D url-loader

modify webpack.config.js

module.exports = {
module: {
rules: [{
test: /\.(png|svg|jpg|gif)$/,
use: {
loader: 'url-loader',
options: {
limit: 3 * 1024 // No more than 3k The image will be converted to base64
}
}
}]
}
}

4.2 To configure CDN

modify publicPath To configure :

module.exports = {
output: {
publicPath: 'http://xxx.com/img/'
}
}

webpack The results are as follows :

<body>
<img src="http://xxx.com/img/xxxxxx.png" />
<script src="http://xxx.com/img/main.js"></script>
</body>

4.3 HTML and CSS Use in alias

modify webpack Of alias To configure

module.exports = {
resolve: {
alias: {
'@assets': path.resolve(__dirname, './src/assets')
}
}
}

stay html Use in alias:

<img src="~@assets/img/large.png" />

stay css Use in alias:

.bg-img {
background: url(~@assets/img/small.png) no-repeat;
}

Tips: stay HTML and CSS Use alias You have to add ~ about svg Pictures can be used svg-url-loader Handle

4.4 Use img-webpack-loader Compression optimization picture

install loader:

$ npm install image-webpack-loader --save-dev

image-webpack-loader Embedded images are not supported , So it has to be with url-loader and svg-url-loader Use it together :

module.exports = {
module: {
rules: [{
test: /\.(jpe?g|png|gif|svg)$/,
loader: 'image-webpack-loader',
enforce: 'pre' // Raise the priority , stay url-loader and svg-url-loader Before the completion of image optimization , Avoid multiple loader Repeated references in
}]
}
};

4.5 Use PostCSS Generate CSS Sprite Sprite

install loader:

$ npm install postcss-sprites -D
$ npm install postcss-loader -D

modify PostCSS Of postcss.config.js, Add plug-in call :

// postcss.config.js
const postcssSprites = require('postcss-sprites');
module.exports = {
plugins: [
postcssSprites({
spritePath: './src/assets/img/' // Only images in the specified path will be processed as sprites
})
]
};

To configure loader, Order of attention :

{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader', {
loader: 'postcss-loader'
}
]
}

After completion , The image below will be processed as sprite :

/* Before packing */
.bg-img01 {
background: url(./assets/img/small-01.png) no-repeat;
}
.bg-img02 {
background: url(./assets/img/small-02.png) no-repeat;
}
/* After packing */
.bg-img01 {
background-image: url(xxxxxx.png);
background-position: 0px 0px;
background-size: 320px 320px;
}
.bg-img02 {
background-image: url(xxxxxx.png);
background-position: -160px 0px;
background-size: 320px 320px;
}

4.6 Use file-loader / url-loader Handle Fonts 、 Rich media resources

If you don't need Base64 You can use it directly file-loader, Otherwise, use url-loader:

{
// File parsing
test: /\.(eot|woff|ttf|woff2|appcache|mp4|pdf)(\?|$)/,
loader: 'file-loader',
query: {
// So many files ,ext Different , So we need to use [ext]
name: 'assets/[name].[hash:7].[ext]'
}
}

4.7 Use loader Import data resources

JSON / CSV / TSV / XML Format resources can be mapped to loader Import as resolved JSON For ease of use . among ,JSON Of loader It's built in , It can be used directly .

import Data from'./data.json'

For the other three data formats , First, install the corresponding loader:

$ npm i -D xml-loader csv-loader

And then modify webpack To configure :

{
test: /\.(csv|tsv)$/,
use: ['csv-loader']
}, {
test: /\.xml$/,
use: ['xml-loader']
}

5. HTML And multi page configuration

5.1 HTML Document processing

install loader:

Regularize (test) Put together , Then you need to use ext Configure the filename of the output .

$ npm i html-webpack-plugin --save-dev

Configuration plug-ins :

const HtmlWebPackPlugin = require('html-webpack-plugin');
module.exports = {
mode: 'development',
entry: {
main: './src/index.js'
},
plugins: [
// case1: stay dist Automatically generate a index.html The file of , Automatically insert the entry file main.js
new HtmlWebPackPlugin(),
// case2: Modify the automatically generated html File parameters
new HtmlWebPackPlugin({ title: 'hello', filename: 'foo.html' }),
// case3: Use template Template file generation html file
new HtmlWebPackPlugin({ template: './src/index.html' })
]
};

5.2 Multi entry page configuration

For multi entry html Pages can be implemented by multiple instantiations of plug-ins , But just configure plug-ins , The entrance of the introduction js The files are the same main.js, At this time, we need to use html-webpack-plugin Two parameters of the plug-in chunks and excludeChunks To solve .chunks Indicates that the current page contains chunk, Can correspond to entry Of key,excludeChunks It is to exclude some chunks. for example :

const HtmlWebPackPlugin = require('html-webpack-plugin');
module.exports = {
mode: 'development',
entry: {
index: './src/index.js',
list: './src/list.js'
},
plugins: [new HtmlWebPackPlugin({
template: './src/index.html',
filename: 'index.html',
chunks: ['index']
}), new HtmlWebPackPlugin({
template: './src/list.html',
filename: 'list.html',
chunks: ['list']
})]
};

Tips: For multi page applications , Consider using glob And other modules automatically load templates and entry files to achieve automatic loading

6. js Compression processing

stay webpack 4 Of production A large number of general optimization configurations have been made under the mode , Such as Tree-Shaking、Scope Hoisting It's on by default , The compression tool used is terser-webpack-plugin, It's from uglify-es Pull a branch of the project to continue maintenance , With and uglifyjs-webpack-plugin Same parameters .

const TerserPlugin = require('terser-webpack-plugin');
module.exports = {
optimization: {
minimizer: [
new TerserPlugin(
parallel: true, // Multithreading
comments: false,
compress: {
unused: true,
drop_debugger: true, // Delete debugger
drop_console: true, // remove console
dead_code: true // Remove useless code
}
)]
}
};

Scope Hoisting Scope escalation refers to webpack adopt ES6 Syntax statically analyzes the dependencies between modules , Put modules in the same function as much as possible , Give Way webpack The packaged code file is smaller 、 Run faster . Other code level optimization techniques :

  • Reasonable division of code responsibilities , Load appropriately on demand
  • Setting up reasonable SplitChunks grouping
  • The rational use of hash Place holder , Prevent the file name from changing HTTP Cache expiration
  • The rational use of polyfill, Reduce the generation of redundant code
  • Use ES6 grammar , Reduce the use of code with side effects to enhance Tree-Shaking effect
  • Use Webpack Of Scope Hoisting( Scope promotion ) function
  • Use bable-plugin-import And so on UI Component library
  • Make good use of webpack-bundle-analyzer plug-in unit , Help analyze Webpack Packaged module dependencies

7. Cache optimization strategy

Static resources can be set http Cache policy , Such as :

Cache-Control: max-age=31536000

7.1 chunk Code splitting

When using chunkhash when , Thanks to caching strategy , Code splitting and on-demand loading are important ,webpack Of chunk There are three ways to split code :

  • entry To configure : Configure multiple entry Entrance file
  • dynamic ( On demand ) load : Active use in code import() or require.ensure
  • Extract common code : Use splitChunks To configure
module.exports = {
// ...
optimization: {
splitChunks: {
chunks: 'async', // "initial" | "all" | "async" ( Default )
minSize: 30000, // The minimum size of the file ,30K,development Next is 10k, If it's very high , Then the public part is not extracted , But on demand loading still extracts
maxSize: 0, // The maximum size of the document ,0 For no limit , priority :maxInitialRequest/maxAsyncRequests < maxSize < minSize
minChunks: 1, // Default 1, One module to be extracted needs to be at least a few chunk Cited in , The bigger this is , The smaller the extracted file is
maxAsyncRequests: 5, // How many asynchronous requests are there at most when doing an on-demand load , by 1 You don't draw public chunk 了
maxInitialRequests: 3, // In view of a entry The maximum number of files for initialization module partition , Priority over cacheGroup, So for 1 When You don't extract initial common 了
automaticNameDelimiter: '~', // Package file name separator
name: true, // The name of the split file , The default is true, Represents the automatically generated file name , If set to a fixed string, then all chunk Will be combined And become a
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/, // Regular rule , If it matches, extract chunk
priority: -10 // Cache group priority , When a module may belong to more than one chunkGroup, Here's the priority
},
default: {
minChunks: 2,
priority: -20, // priority
reuseExistingChunk: true // If it's time to chunk Contains modules It's already another divided chunk in , So direct reference to what already exists c hunk, There will be no more
}
}
}
}
};
sign

Original statement , This article is authorized by the author + Community publication , Unauthorized , Shall not be reproduced .

If there is any infringement , Please contact the yunjia_community@tencent.com Delete .

版权声明
本文为[CS Xiaoyao Sword Fairy]所创,转载请带上原文链接,感谢
https://qdmana.com/2021/02/20210221215035485E.html

  1. An inexperienced front-end engineer, what are the common problems when writing CSS?
  2. HttpServletRequest get URL (parameter, path, port number, protocol, etc.) details
  3. Springboot starts http2
  4. Enabling http2.0 in spring boot
  5. JQuery:JQuery基本语法,JQuery选择器,JQuery DOM,综合案例 复选框,综合案例 随机图片
  6. Using JavaScript in Safari browser history.back () the page will not refresh after returning to the previous page
  7. vue.js Error in win10 NPM install
  8. In less than two months, musk made more than $1 billion, more than Tesla's annual profit
  9. Springboot starts http2
  10. Vue event bus
  11. JQuery easy UI tutorial: custom data grid Pagination
  12. Using okhttp and okhttpgo to obtain onenet cloud platform data
  13. Vue3 component (IX) Vue + element plus + JSON = dynamic rendering form control
  14. HTTP 1. X learning notes: an authoritative guide to Web Performance
  15. Vue3 component (IX) Vue + element plus + JSON = dynamic rendering form control
  16. HTTP 1. X learning notes: an authoritative guide to Web Performance
  17. JQuery:JQuery基本语法,JQuery选择器,JQuery DOM,综合案例 复选框,综合案例 随机图片
  18. Event bubble and capture in JavaScript
  19. The root element is missing solution
  20. Event bubble and capture in JavaScript
  21. Configure the certificate to enable ngnix to publish the trusted website of HTTPS
  22. Javascript数据类型
  23. HTTP interface debugging tool! 48000 star HTTP command line client!
  24. Parameter encryption of front end URL link band
  25. HTTP interface debugging tool! 48000 star HTTP command line client!
  26. Three front end frameworks: data binding and data flow
  27. Reading Axios source code (1) -- exploring the realization of basic ability
  28. Event bubble and capture in JavaScript
  29. 【微前端】微前端最終章-qiankun指南以及微前端整體探索
  30. R & D solution e-Car front end monitoring system
  31. [JS] 877 - 35 wonderful knowledge of JavaScript, long experience!
  32. R & D solution e-Car front end monitoring system
  33. High performance nginx HTTPS tuning - how to speed up HTTPS by 30%
  34. 解决ajax跨域问题【5种解决方案】
  35. Top ten classic sorting of JavaScript
  36. HTTP 1. X learning notes: an authoritative guide to Web Performance
  37. Vue3 component (IX) Vue + element plus + JSON = dynamic rendering form control component
  38. My http / 1.1 is so slow!
  39. Why Vue uses asynchronous rendering
  40. The response status was 0. Check out the W3C XMLHttpRequest Level 2 spec for
  41. The tapable instance object hook of webpack4. X core tool library
  42. The tapable instance object hook of webpack4. X core tool library
  43. Using libcurl for HTTP communication in C + +
  44. Using libcurl for HTTP communication in C + +
  45. Using CSS variable in Vue
  46. Deeply understand the update of state and props in react
  47. No matter how fast the Internet is, it's useless! In addition to Baidu disk, there is this website slow to let you eat shriveled
  48. Baidu share does not support the solution of HTTPS
  49. [micro front end] the final chapter of micro front end - Qiankun guide and overall exploration of micro front end
  50. [micro front end] the final chapter of micro front end - Qiankun guide and overall exploration of micro front end
  51. Vue cli creates vue3 project
  52. Nginx reverse proxy for windows authentication using NTLM
  53. Rust tutorial: introduction to rust for JavaScript developers
  54. Deploying personal blog to Tencent cloud with serverless framework
  55. R & D solution e-Car front end monitoring system
  56. JavaScript advanced learning
  57. Spend 1 minute to master these 5 ppt tips, courseware making less detours
  58. Vue: vuex persistent state
  59. React native gets the current network state of the device Netinfo
  60. High performance nginx HTTPS tuning - how to speed up HTTPS by 30%