Webpack

1. The webpack is introduced

Webpack is essentially a static module packaging tool for modern JS applications. When WebPack processes an application, it internally builds a dependency diagram that maps to each module required for the project and generates one or more bundles.

Installed 1.1.

  • Webpack core packages
  • Webpack – CLI command line toolkit
npm install webpack webpack-cli -D
Copy the code

1.2. The entry (entry)

  • Entry point indicationwebpackWhich module the application uses to start building the internal dependency map. After entering the entry point,webpackIt finds out which modules and libraries are dependent on the entry point.
  • The default value is./src/index.jsWe can go throughwebpack configIn theentryProperty to specifyOne/moreDifferent entry points.
module.exports={
    entry:'./src/index.js'
}
Copy the code

1.3. Exports (output)

  • outputProperty, tellwebpackWhere does it output its creationbundleAnd hownamedThese documents.
  • The default value for the main output file is./dist/main.js, other generated file default values are placed in./distFolder.
attribute describe
filename The file name
path The path of the packed file
publicPath Generally, it is set to ‘/’ and inserted into the path in SRC: publicPath+filename
const path=require('path')
module.exports={
    output: {filename:'main.js'.path:path.resolve(__dirname,'dist')}}Copy the code

1.4. Loader

  • webpackCan only understandjsandjsonFile.
  • loaderletwebpackThe ability to process other types of files and convert them into valid modules for use by applications, as well as dependency diagrams to be added
module: {rules:[
    {test:/\.txt$/,use:'raw-loader'}}]Copy the code

1.5. The plugin (plugins)

  • Loaders are used to convert certain types of modules, while plug-ins can be used to perform a wider range of tasks. Including: package optimization, resource management, injection of environment variables.
const HtmlWebpackPlugin=require('html-webpack-plugin');
plugins:[
  new HtmlWebpackPlugin({
    template:'./src/index.html'})]Copy the code

1.6. Mode (mode)

  • In front-end development, there are typically two sets of environments
  • Development environment, build results for local development debugging, no code compression, printdebugInformation, includingsourcemapfile
  • In production, the code is compressed and run without printingdebugInformation that static files do not containsourcemap
1.6.1. Environmental differences
  • Development Environment
    • The SourcemAP file needs to be produced
    • Debug information needs to be printed
    • You need live reload or hot Reload
  • Production environment
    • You may need to separate the CSS into separate files so that multiple pages share the same CSS file
    • Need to compress HTML/CSS/JS code
    • I need to compress the image
  • The default value is production
1.6.2. Differentiate the environment
  • --mode: used to set up the moduleprocess.env.NODE_ENV
  • --env: used to set function parameters for the WebPack configuration file
  • cross-env: used to set the Node environmentprocess.env.NODE_ENV
  • DefinePlugin: used to set global variables in a module
1.6.2.1. Cli Configuration 1

Webpack mode defaults to Production

Webpack Serve defaults to Development

The current environment variable is available through process.node_env, not in the Webpack configuration file

"scripts": {
    "start":"webpack serve"."build":"webpack"
}
Copy the code
  • index.js
console.log(process.env.NODE_ENV);//production | development
Copy the code
  • webpack.config.js
console.log(process.env.NODE_ENV);//undefined
Copy the code
1.6.2.2. Cli Configuration 2
"scripts": {
    "start":"webpack serve --mode=development"."build":"webpack --mode=production"
}
Copy the code
1.6.2.3. Cli Configuration 3
"scripts": {
    "start":"webpack serve --env=development"."build":"webpack --env=production"
}
Copy the code
1.6.2.4. Mode configuration
module.exports={
  mode:'development'
}
Copy the code
1.6.2.5. DefinePlugin
  • Set global variables (nowindow), all modules can read the value of this variable
  • Can pass in any moduleprocess.env.NODE_ENVGets the current environment variable
  • Can’t inThe node environmentGets the current environment variable (in the WebPack configuration file)
new webpack.DefinePlugin({
    PRODUCTION: JSON.stringify(true),
    VERSION: JSON.stringify('1.1.0'),
    BROWSER_SUPPORTS_HTML5: true.TWO: '1 + 1',})Copy the code
  • index.js
// eval()
console.log('PRODUCTION',PRODUCTION);//true
console.log("VERSION",VERSION);/ / 1.1.0
console.log("BROWSER_SUPPORTS_HTML5",BROWSER_SUPPORTS_HTML5);//true
console.log("TWO",TWO);/ / 2
Copy the code
1.6.2.6. Cross – env
  • Can only be setThe node environmentThe variables underNODE_ENV
"scripts": {
  "build": "cross-env NODE_ENV=development webpack"
}
Copy the code
  • webpack.config.js
console.log('process.env.NODE_ENV',process.env.NODE_ENV);// development
Copy the code

2. Configure the development environment

  • DevServer starts an HTTP development server with a folder as a static root directory
  • To improve performance, the memory file system used (memory-FS)
  • By default, devServer reads the packaged path

2.1. Development server

2.1.1. Install the server
npm install webpack-dev-server -D
Copy the code
2.1.2. Parameter
attribute describe
port Specifies the port number of the HTTP server
compress Whether to enable gzip compression
contentBase Static file root directory
open Automatically open the browser
writeToDisk It will write a copy of the packed file to the hard drive
publicPath:http://locahost/8080/assets/ Is there byhttp://localhost:8080/assets/ to access the static resources after packaging
devServer: {
    contentBase: path.resolve(__dirname,'static'),
    compress:true.port:8080.open: true
}
Copy the code
start:'webpack serve'//5.x
start:'webpack-dev-server'//4.x
Copy the code

2.2 support CSS

  • css-loaderTo deal with@importandurl();
  • Insert style-loaderCSS into the DOM;

2.2.1. Install plug-ins

npm install style-loader css-loader -D
Copy the code

Webpack.config. js, loader is in order, from right to left

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

src/bg.css

body{
  background:red;
}
Copy the code

src/index.css

@import './bg.css';
body{
  color:blue;
}
Copy the code

src/index.html

import './index.css'
Copy the code

2.3 support less&sass

2.3.1. Install
npm install less less-loader -D
npm install node-sass sass-loader -D
Copy the code
2.3.2. Use

webpack.config.js

module: {rules:[
        {test:/\.css$/i,use:['style-loader'.'css-loader'] {},test:/\.less$/i,use:['style-loader'.'css-loader'.'less-loader'] {},test:/\.scss$/i,use:['style-loader'.'css-loader'.'sass-loader']},]}Copy the code

src/index.html

<div id="less-container">less-container</div>
<div id="sass-container">sass-container</div>
Copy the code

src/index.js

import './less.less';
import './sass.scss';
Copy the code

src/less.less

@color:oranger;
#less-container{
    color: @color;
}
Copy the code

src/sass/scss

$color:green;
#sass-container{
    color: $color;
}
Copy the code

2.4. Images are supported

Installation against 2.4.1.
  • File-loader Resolves the problem of image paths in files such as the CSS
  • url-loaderPicture is less thanlimitWhen will put the picturebase54Code, greater thanlimitParameter is still usedfile-loaderTo copy
npm install file-loader url-loader html-loader -D
Copy the code
Use 2.4.2.

webpack.config.js

Url-loader is an enhancement of file-loader

{ test: /\.html$/, loader: 'html-loader' },
{
    test: /\.(jpg|png|bmp|gif|svg)$/, use: [{
        loader: 'url-loader'.options: {
            esModule: false.// This is true by default
            name: '[hash:10].[ext]'.// Take the hash tens place as the image name, ext is the extension,f0a12b17c9.png
            limit: 8 * 1024// If the size of the file is smaller than limit, it is converted to base64 strings embedded in HTML}}}]Copy the code

Index.html, which uses images in HTML

<img src="./images/logo.png" alt="logo.png">/ / need HTML - loader + url loader/file - loaderCopy the code

Js. Set esModule to false in the configuration. Otherwise, use logo.default and use file-loader/url-loader

const logo=require('.. /static/logo.png')
const img=new Image();
img.src=logo;
document.body.appendChild(img);
Copy the code

Index.css, urls in the CSS use images. File-loader /url-loader is used

#img-container{
    width: 400px;
    height: 103px;
    background: url('.. /static/logo.png');
}
Copy the code

2.5.JS Compatibility Processing

Babel is a platform for compiling javascript and escaping ES6/ES7,React,JSX to ES5

The default is a collection of plug-ins

  • Babel-loader: calls Babel /core

  • @babel/core: Core package compiled by Babel, ES6 is converted to ES6 syntax tree, ES6 is converted to ES5 syntax tree via Babel/Core, ES5 syntax tree is converted to ES5 code

  • @babel/preset-env: Syntax conversion is supported by default

  • @babel/preset-react: The react plugin’s Babel preset

  • Babel/plugin-proposL-decorators: compile class and object decorators into ES5

  • Babel /plugin-proposal-class-proterties: translate static class attributes and use attributes to initialize syntactically declared attributes

2.5.1. Install
npm install babel-loader @babel/core @babel/preset-env @babel/preset-react -D
npm install @babel/plugin-proposal-decoreators @babel/plugin-proposal-class-properties -D
Copy the code
2.5.2. Use
{
  test:/\.jsx? $/,
  use:[
    loader:'babel/loader'./ / called Babel/core
    options: {presets: ['@babel/preset-env'.// Convert ES6 to ES5 syntax tree
    		'@babel/preset-react'// Convert JSX syntax].plugins: [// These two plugins are in order
        ['@babel/plugin-proposal-decorators', {legacy:true}].// Convert classes and objects
        ['@babel/plugin-proposal-class-properties', {loose:true}]// Convert static class attributes]]}}Copy the code

Solve the ES6 – > ES5

let sum = (a, b) = > a + b;
Copy the code

To solve the React

import React from 'react';
import ReactDOM from 'react-dom';

ReactDOM.render(<h1>hello word</h1>.document.getElementById('root'));
Copy the code

Solution decorator

/ * * * *@param {*} Target The target of the decoration@param {*} Key Decorated key *@param {*} Descriptor Property description of the descriptor */
function readonly(target,key,descriptor){
    descriptor.writable=false;
}
class Person{
    @readonly PI=3.14;
}
Copy the code
2.5.3. Compatibility processing

@babel/preset-env: Syntax conversion is supported by default, useBuiltIns needs to be enabled to convert apis and instance methods

  • The latest ES syntax: for example, arrow functions
  • The latest ES API: For example, Promise
  • The latest ES instance methods: String. For example, the prototype. Includes

webpack.config.js

{
  test:/\.jsx? $/,
  use:[{
    loader:'babel-loader'.options: {presets:[
        ['@babel/preset-env': {useBuiltIns:'usage'./ / load polyfill
         corejs: {version:3},// Specify the version of Corejs
         target: {// Specify compatible browsers
        	chrome:'60'./ /...}}]]}}Copy the code

useBuiltIns

  • False, do not do polyfill, if introduced@babel/polyfillIgnore the configured browser and import allpolyfill
  • Entry, based on the configuration of browser compatibility, introduces browser incompatible polyfill. It needs to be added manually in the entry fileimport @babel/polyfill, will automatically rootbrowserslistReplace all polyfills that are browser incompatible;
  • Usage, polyfill based on configured browser compatibility and API used in the code to achieve on-demand loading.
2.5.4. Polyfill – service
  • Polyfills. IO: The polyfills needed to automatically load the browser
<script src="https://polyfill.io/v3/polyfill.min.js"></script>
Copy the code
2.5.5. Babel – the runtime
  • Babel offers a separate package to address the global problem of space pollutionbabel-runtimeUtility functions to provide for compiling modules
  • In a nutshellbabel-runtimeIt’s more of an on-demand implementation, like where do I need to use Promise, just in the header of the fileimport Promise from 'babel-runtime/core-js/promise'You can
import Promise from 'babel-runtime/core-js/promise';

const p = new Promise((resolve) = > {
    resolve('ok');
});

p.then((data) = > console.log(data));
Copy the code

Rewrite the Promise method instead of contaminating the whole world, the downside is that it needs to be introduced every time

2.5.6. @ Babel/plugin – transform – runtime
  • To enable the plugin@babel/plugin-transform-runtimeThen Babel will use itbabel-runtimeBelow the utility function
  • @babel/plugin-transform-runtimePlug-ins can convert the code of these utility functions intorequireStatement, pointing to a pairbabel-runtimeA reference to the
  • @babel/plugin-transform-runtimeIt’s automatic when we use a new APIimport babel-runtimeThe inside of the ` polyfill
Copy the code
plugins: [
  [
    "@babel/plugin-transform-runtime",
    {
      corejs: 2.// Babel-Runtime /core-js is automatically introduced when we use ES6 static events or built-in objects
      helpers: true.// Remove inline Babel helpers and replace them with babel-Runtime /helpers
      regenerator: true.// Whether to enable generator function conversion to use ReGenerator Runtime to avoid global contamination},], ['@babel/plugin-proposal-decorators', { legacy: true }],
  ['@babel/plugin-proposal-class-properties', { loose: true}]].Copy the code

Best practices

Babel-runtime is suitable for use in component and library projects, while Babel-Polyfill is suitable for use in business projects

2.6.ESLint code verification

2.6.1. Install
npm install eslint eslint-loader babel-eslint -D
Copy the code
Use 2.6.2.

webpack.config.js

{
  test:/\.jsx? $/,
  loader:'eslint-loader'.enforce:'pre'.Pre ->normal->inline-> POST
  options: {fix:true},// Start automatic repair
  include:path.resolve(__dirname,'src'),// Test only SRC
  exclude:/node_modules/./ / node_modules ruled out
}
Copy the code

.eslintrc.js

module.exports = {
    root: true.parser: "babel-eslint".// Specify parser options
    parserOptions: {
        sourceType: "module".ecmaVersion: 2015
    },
    // Specify the runtime environment for the script
    env: {
        browser: true,},// The enabled rules and their respective error levels
    rules: {
        "indent": ['error'.4].// Indent style
        "quotes": "off".// Quotes
        "no-console": "off".// Disable console}}Copy the code
2.6.3. Best Practices (Airbnb)

The installation

npm install eslint-config-airbnb eslint-loader eslint eslint-plugin-import eslint-plugin-react eslint-plugin-react-hooks and eslint-plugin-jsx-a11y -D
Copy the code

.eslintrc.js

module.exports = {
    parser:"babel-eslint".extends:"airbnb".rules: {"semi":"error"."no-console":"off"."linebreak-style":"off"."eol-last":"off"
        "indent": ["error".4]},env: {"browser":true."node":true}}Copy the code
2.6.4. Automatic repair
  • Install the eslint plugin for vscode
  • Configure automatic repair parameters

.vscode/settings.json

{
    "editor.codeActionsOnSave": {
        "source.fixAll.eslint": true}},Copy the code

2.7. Sourcemap

Sourcemap is a technology designed to help us debug the original development code when it is inconsistent with the actual running code.

devtool: 'hidden-source-map'
Copy the code
2.7.1. Configuration items
type meaning
source-map Original code, but compilation speed is slow
eval-source-map The raw code, as opposed to source-map, is cached, faster,eval
cheap-module-eval-source-map The original code (inline only) does the same, but with higher quality and lower performance
eval Production code, each module is executed by eval, and there is a sourceUrl. Build mode with eval can cache
cheap-source-map Conversion code, no column information, from loaders to live sourcemap is not used
cheap-module-source-map There is no row information, there is loader mapping
cheap-eval-source-map The conversion code, with no column information, is executed by EVAL for each module, and sourcemap acts as a dataUrl for Eval
2.7.2. Best practices

The development environment

Development environment requirements for sourceMap: fast speed, debugging friendly

  • For speed, eval-cheap-source-map is recommended

  • Cheap -module-source-map is recommended for friendlier debugging

  • Compromise: eval-source-map

The production environment

Inlining is excluded first, because we want to hide the source code and reduce the file size

  • To debug friendly:sourcemap>cheap-source-map/cheap-module-source-map>hidden-source-map/nosources-sourcemap
  • To be fast, choose firstcheap
  • compromisehidden-source-map

2.8. Beat third-party libraries

  • Direct introduction:import
  • Plug-in to introduce
  • expose-loader
  • externals
  • Http-webpack-externals-plugin
2.8.1. Direct introduction

It’s a bit of a hassle, you have to introduce it every time

import _ from 'lodash';

alert(_.join(['a'.'b'.'c'].'_'));
Copy the code
2.8.2. Plug-in introduction

After webpack is configured with ProvidePlugin, import/require is no longer needed during use, and can be used directly.

The _ function is automatically added to the context of the current module without requiring a declaration

new webpack.ProvidePlugin({
     _:'lodash'
})
Copy the code
2.8.3. Expose – loader
  • expose-loader: You can add modules to global objects, which is useful for debugging
  • You don’t need any other plug-ins, just add the following code to allloaderbefore
npm install expose-loader -D
Copy the code
//=> Import file
require('lodash');

//=>webpack.config.js
  module: {
    rules: [{test: require.resolve('lodash'),
          loader: 'expose-loader'.options: {
              exposes: {
                  globalName: '_'.override: true,},},}]}Copy the code
2.8.4. Externals

If we want to introduce a library, but we don’t want webpack, and we don’t want to use it as CMD,AMD, or Window /global in our application, we can configure externals

  • index.html
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
Copy the code
  • index.js
require('lodash');
Copy the code
  • webpack.config.js
{
  externals: {lodash:'_'}}Copy the code
2.8.5. HTML – webpack – externals – the plugin
npm install html-webpack-externals-plugin  -D
Copy the code
const HtmlWebpackExternalsPlugin = require('html-webpack-externals-plugin');
new HtmlWebpackExternalsPlugin({
    externals: [{module: 'lodash'./ / module name
            entry: "https://cdn.bootcdn.net/ajax/libs/lodash.js/4.17.20/lodash.js".global: '_'.// Global variable name},]}),Copy the code

2.9. Mode&env & cross – env

  • webpack --mode=development: Changes the mode value, which can be passed in the codeprocess.env.NODE_ENVGet the mode value;
  • webpack --env=development: What has changed is thatwebpack.config.jsDerived function parameters inenvThe value of the;
  • cross-env NODE_ENV=development webpack serve: What has changed is thatwebpack.config.jsIn theprocess.env.NODE_ENVThe value of the;
2.9.1.--mode

package.json

"start:mode":"webpack serve --mode=development"
Copy the code

index.js

console.log(process.env.NODE_ENV);//=>development
Copy the code
2.9.2.--env

package.json

"start:env":"webpack serve --env=development"
Copy the code

webpack.config.js

module.exports=(env) = >{
  console.log(env.development);
}
Copy the code
2.9.3.cross-env

package.json

"start:cross":"cross-env NODE_ENV=development webpack serve"
Copy the code

webpack.config.js

console.log(process.env.NODE_ENV);//=>development
Copy the code

2.10. Code debugging

2.10.1. Test environment debugging
  • source-map-dev-tool-plugin: Realize the generation of source map, for more fine-grained control
    • filenam: Defines the name of the generated Source map (inlined if there is no value)
    • append: Appends the given value to the original resource. Is usually#sourceMappingURLThe comments.[url]Is replaced with the URL of the source map file
  • There are two popular forms of document definition,#and@The symbol begins,@The beginning has been abandoned
Installed 2.10.2.
npm install e
Copy the code
Use 2.10.3.
const FileManagerPlugin=require('file-manager-plugin');
const webpack=require('webpack');
module.exports={
  plugins: [new webpack.SourceMapDevToolPlugin({
      filename:'[file].map'.append:'\n//# sourceMappingURL=http://localhost:8081/[url]'
    }),
    new FileManagerPlugin({
      events: {onEnd: {copy: [{source:'./dist/*.map'.destination:'/ Users/dufeihu/Documents/HTML/zhufeng/review/day22 - webpack sourcemap'// Append to the packaged code to find the address mapping sourcemap}].delete: ['./dist/*.map']}}})]}Copy the code
2.10.4. Production environment test

The WebPack package still generates sourceMap, but the map file is picked out and placed on the local server, deploying to the server without the map file

2.11. Watch

Automatically rebuild when code changes

module.exports = {
  watch: true.// The default is false and you need to start manually
  watchOptions: { / / watch properties
  ignored: /node_modules/.// Files/folders that are not monitored and support re
  aggregateTimeout: 300.// Wait 300 milliseconds after listening for file changes. The default value is 300ms
  poll: 1000.// Polling times, 1000 times per second, default value 1000/m}}Copy the code

2.12. Copying static files

Copy-webpack-plugin copies source files to the target directory

2.12.1. Install
npm install copy-webpack-plugin -D
Copy the code
Use 2.12.2.
const CopyWebpackPlugin = require('copy-webpack-plugin');

new CopyWebpackPlugin({
  patterns: [{
    from: path.resolve(__dirname,'static'),// Static resource directory source address
    to: path.resolve(__dirname,'dist/static'), // Target address, relative to the path of output}],}).Copy the code

2.13. Clear the dist directory

Clean-webpack-plugin can be used to clean the output directory before packaging

Installed 2.13.1.
npm install clean-webpack-plugin -D
Copy the code
2.13.2. Use
const CleanWebpackPlugin=require('clean-webpack-plugin');
module.exports={
  output: {filename:'[name][hash:10].js'.path:path.resolve(__dirname,'dist')},plugins: [new CleanWebpackPlugin({
      cleanOnceBeforeBuildPatterns: ['* * / *']]}})Copy the code

2.14. Server proxy

Proxy urls can be useful if you have a separate backend development server API and want to send API requests under the same name

2.14.1. Do not modify the path

The request to the API/users will now be agent to request http://localhost:3000/api/users

/ * * * request address: http://localhost:8080/api/users * agent address: http://localhost:3000/api/users * /
devServer: {
  proxy: {
    "/api": 'http://localhost:3000'}}Copy the code
2.14.2. Modifying a path
/ * * * request address: http://localhost:8080/api/users * agent address: http://localhost:3000/users * /
devServer: {
  proxy: {
      "/api": {
       target: 'http://localhost:3000'.pathRewrite: {"^/api":""}}}}Copy the code
2.14.3. Before after

Before can be used to intercept partial requests to return specific content, or to implement simple data mocks, before being processed by the static resource middleware of Webpack-Dev-server

devServer: {
  before(app){
    // App is an express()
    app.get('/api/users'.function(req, res) { 
       res.json([{ name: 'lisi'.age: 20}]); }}})Copy the code
2.14.4. Webpack – dev – middleware

Webpack-dev-middleware is a middleware that provides webpack-dev-server static service capabilities in Express

  • webpack-dev-serverThe advantage is relatively simple, directly install the dependency after the command can be executed
  • usewebpack-dev-middlewareThe advantages can be found in bothexpressQuick additions to the code basewebpack-dev-serverFunction while utilizingexpressTo add more functionality as needed

The installation

npm install webpack-dev-middleware -D
Copy the code

use

const express = require('express');
const app = express();
const webpack = require('webpack');
const webpackDevMiddleware = require('webpack-dev-middleware');
const webpackOptions = require('./webpack.config');
webpackOptions.mode = 'development';
const compiler = webpack(webpackOptions);
app.use(webpackDevMiddleware(compiler, {}));
app.listen(3000);
Copy the code

3. Production environment

3.1. Extract the CSS

Because CSS downloads and JS can be done in parallel, when an HTML file is large, we can pull out the CSS and load it separately

3.1.1 the installation
  • mini-css-extract-plugin
npm install mini-css-extract-plugin -D
Copy the code
3.1.2. Use
  • webpack.config.js
const MiniCSSExtractPlugin=require('mini-css-extract-plugin');

module.exports={
  output: {path:path.resolve(__dirname,'dist'),
    filename:'[name].js'.publicPath:'/'
  },
  module: {rules: [/ / replace before style - loader, use MiniCSSExtractPlugin. Loader
      {
        test:/\.css$/,
        use:[MiniCSSExtractPlugin.loader,'css-loader'] {},test:/\.less$/,
        use:[MiniCSSExtractPlugin.loader,'css-loader'.'less-loader'] {},test:/\.scss$/,
        use:[MiniCSSExtractPlugin.loader,'css-loader'.'sass-loader']},]},plugins: [new MiniCSSExtractPlugin({
      filename:'[name].css'}})]Copy the code

3.2. Specify the image and CSS directory

3.2.1.webpack.config.js
module.exports={
  module: {rulues:[
      {
        test:/\.(jpg|png|gif|bmp|svg)$/,
        use:[{
          loader:'url-loader'.options: {esModule:false.name:'[hash:10].[ext]'.limit:8*1028.outputPath:'images'.publicPath:'/images'}}]}plugins: [new MiniCSSExtractPlugin({
  		filename:'css/[name].css'}})]Copy the code

3.3. The hash, chunkhash and contenthash

  • File fingerprintIs the output file name and file suffix after packaging
  • Hash is generally used in combination with CDN cache. After the hash file name is created through Webpack, the corresponding file name is automatically added to the corresponding file namemd5Value. If the file content changes, the corresponding file hash value will also change, and the URL address referenced by the corresponding HTML will also change, triggering the CDN server to pull the corresponding data from the source server, and then update the local cache.

Fingerprint transposition character

Placeholder name meaning
ext Resource name extension
name The file name
path File relative path
folder The folder where the file resides
hash A unique hash value is generated each time a Webpack is built
chunkhash Generate hash values based on chunk. If the values are from the same chunk, the hash values are the same
contenthash Generate a hash value based on the content. If the file content is the same, the hash value is the same

3.4. The CSS compatibility

  • For browser compatibility, sometimes we have to-webkit.-ms.-o.-mozThe prefix
    • Trident kernel: indicates the Internet Explorer. The prefix is-ms
    • Gecko kernel: Mainly represents Firefox. The prefix is-moz
    • Presto kernel: mainly represents Opera with a prefix of-o
    • Webkit kernel: Mainly represents Chrome and Safari. The prefix is-webkit
  • Pseudo elements::placeholderYou can select placeholder text for a form element, which allows developers and designers to customize the style of placeholder text
Installed 3.4.1 track.
  • Postcss-loader: PostCSS can be used to process CSS
  • Postcss-preset -env: Turn modern CSS into something that most browsers can understand
  • The PostCSS Preset Env is already includedautoprefixerandbrowsersoptions
npm install postcss-loader postcss-preset-env -D
Copy the code
3.4.2. Postcss. Config. Js
const postcssPresetEnv = require('postcss-preset-env');

module.exports = {
    plugins: [postcssPresetEnv()],
};
Copy the code
Rule 3.4.3. Webpack. Config. Js
module.exports={
  module: {rules:[
      {
        test:/\.css$/,
      use:[MiniCSSExtractPlugin.loader,'css-loader'.'postcss-loader'] {},test:/\.less$/,
      use:[MiniCSSExtractPlugin.loader,'css-loader'.'postcss-loader'.'less-loader'] {},test:/\.scss$/,
      use:[MiniCSSExtractPlugin.loader,'css-loader'.'postcss-loader'.'sass-loader']},]}}Copy the code
3.4.4. Index. The CSS
::placeholder{
    color: red;
}
Copy the code
3.4.5. Index. HTML
<input placeholder="Please enter"/>
Copy the code
3.4.6. Results after compilation
:-moz-placeholder{
    color: red;
}
:-ms-input-placeholder{
    color: red;
}
::placeholder{
    color: red;
}
Copy the code

3.5. Compress JS,CSS and HTML

  • Optimize – CSS-assets-webpack-plugin: is a plugin that optimizes and compresses CSS resources
  • Terser-webpack-plugin is a plugin that optimizes and compresses JS resources
Installed 3.5.1 track of.
npm install optimize-css-assets-webpack-plugin terser-webpack-plugin -D
Copy the code
3.5.2.webpack.config.js
const OptimizeCssAssetsWebpackPlugin=require('optimize-css-assets-webpack-plugin');
const TerserWebpackPlugin=require('terser-webpack-plugin');
const HtmlWebpackPlugin=require('html-webpack-plugin');

module.exports={
  optimization: {minimize:true.minimizer: [new TerserPlugin()
    ]
  },
  plugins: [new HtmlWebpackPlugin({
      template:'./src/index.html'.minify: {collapseWhitespace:true.reomoveComments:true}}),new OptimizeCssAssetWebpackPlugin()
  ]
}
Copy the code

3.6.px automatically changes to REM

  • Lib-flexible + REM, mobile terminal adaptive
  • Px2rem-loader automatically converts PX to REM
  • Calculates the root element when the page is renderedfont-sizevalue
Installed 3.6.1.
npm install px2rem-loader lib-flexible -D
Copy the code
3.6.2. Index. HTML

Implement functions similar to the Lib-flexible library

<script>
	const docEle=document.documentElement;
  function setRemUnit(){
    docEle.style.fontSize=docEle.clientWith/10+'px';
  }
  setRemUnit();
  window.addEventListener('resize',setRemUnit)
</script>
Copy the code
3.6.3. Reset. CSS
* {margin:0;
  padding:0;
}
#root{
  width:750px;
  height:750px;
  border:1px solid red;
  box-sizing:border-box;
}
Copy the code
3.6.4 radar echoes captured. Webpack. Config. Js
module.exports={
  module: {rules:[
      {
        test:/\.css$/,
        use:[{
          MiniCssExtractPlugin.loader,
          'css-loader'.'postcss-loader',
          {
          	loader:'px2rem-loader'.options: {remUnit:75.remPrecesion:8}}}]}}Copy the code

3.7. Multi-entry packing

const fs = require('fs');

const pagesRoot = path.resolve(__dirname, 'src'.'page');
const dirs = fs.readdirSync('./src/page');
const htmlWebpackPlugins = [];
const entry = dirs.reduce((memo, current) = > {
    const name = path.basename(current, '.js');
    // eslint-disable-next-line no-param-reassign
    memo[name] = path.join(pagesRoot, current);
    htmlWebpackPlugins.push(new HtmlWebpackPlugin({
        template: path.resolve(__dirname, './src/index.html'),
        filename: `${name}.html`.chunks: [`${name}`].minify: {
            collapseInlineTagWhitespace: true.removeComments: true,}}));return memo;
}, {});

module.exports{
  entry,
  plugins:[
    ...htmlWebpackPlugins
  ]  
}
Copy the code

3.8. Webpack – merge

Installed 3.8.1.
npm install webpack-merge -D
Copy the code
3.8.2. Webpack. Base. Js
module.exports={
  entry:'./src/index.js'.output: {filename:'[name][hash:10].js'.path:path.resolve(__dirnanem,'dist')}}Copy the code
3.8.3. Webpack. Dev. Js
const merge=require('webpack-merge');
const base=require('./webpack.base.js')
module.exports=merge(base,{
  mode:'development'
})
Copy the code
3.8.4. Webpack. Prod. Js
const merge=require('webpack-merge');
const base=require('./webpack.base.js')
module.exports=merge(base,{
  mode:'production'
})
Copy the code

3.9. Env

  • dotenv
3.9.1. Install
npm install dotenv -D
Copy the code
3.9.2..env
NODE_ENV=development
Copy the code
3.9.3.webpack.config.js
require('dotenv').config();
console.log('process.env.NODE_ENV',process.env.NODE_ENV);//=>development
Copy the code