1. Prevent cache files from appearing after packaging?

Two kinds of schemes

  • Using HASH:Filename: "main.[hash: number].js"
    • You can control the length of the hash value: hash: The length you wantmain.[hash:5].js
    • Prevent caching, a new random string is generated each time, no caching problems
  • Using plug-ins:clean-webpack-pluginClearing cached files
    • If the file is not modified, the execution uses the cached file and is not packaged as a new file
    • Create new files and delete old files

2. How to configure the local service and proxy?

There are two solutions for configuring local services

  • A local service can be opened with webpack-dev-server

    • Configure the package.json file

      "scripts": {
        "start": "webpack-dev-server"
      }
      Copy the code
      • performnpm run start
      • throughLocalhost: 8080Open it in a browser
      • The local service is started successfully
    • Configuration webpack. Config. Js

    DevServer: {port: 9000.open: true.compress: true.contentBase: resolve(__dirname, '.. /public')}Copy the code
    • port:9090“Change the Port number of the Service”
    • open:truE “Automatically open browser after service startup”
      • Or inpackage.jsonadd--openAnd it can be done
    • compress:true“Whether to enable static compression (gzip)”
    • contentBase:resolve(__dirname, '.. /public')
      • publicResources in a file can be requested as a service
      • thepublicThe files under are treated as files on the accessible server
    • hot:true“Hot update”
      • No additional configuration is required and WebPack handles it automatically
    • Before: function (app) {}
      • Interface fakes data, go here before requesting data
  • Install @ webpack – cli/serve

    • configurationpackage.jsonfile
    "scripts": {
      "start": "webpack serve"
    }
    Copy the code
    • Run NPM run start

    • Open it in a browser with localhost: 8080

    • The local service is started successfully

configuration proxyThe agent

Two ways:

  • The first way
Proxy: {'api': {
        target: "Proxy path"
        pathRewrite: {// Path override: everything starting with API is replaced with: ''
            '^/api': ' '}}}Copy the code
  • The second way
proxy: {
	// Any request that contains: "/ API "in the path will be proxied to your configured path
    "/api": "Proxy path"
}  
Copy the code

3. Merge configuration files

With the help of the pluginwebpack-merge: Two objects are merged into one object

Method of use

  • The introduction must use the method of deconstructing assignment
let {merge} = require('webpack-merge');
merge(base, {
  // Here is another configuration file to merge
})
Copy the code

4. Multi-entry packing

  • Entrance to the file

    • Entry is an object configured with multiple entries
    Entry: {index: './src/index.js'.other: './src/other.js'
    }
    Copy the code
  • Output: the export

    • Corresponding to multiple exits:name“Entry defined name” :index/other
output: {
	filename: '[name].[hash:5].js'
}
Copy the code
  • Several pagesnewA fewHtmlWebpackPlugin

5. Webpack plug-ins

clean-webpack-plugin: Clears the cache of packaged files

  • describe
    • Delete the old resource file before putting in the newly packaged one
  • The introduction of
let {CleanWebpackPlugin} = require('clean-webpack-plugin')
Copy the code
  • Usage:
Plugins:new CleanWebpackPlugin()
]
Copy the code
  • Configuration items:cleanOnceBeforeBuildPatterns
    • All old resources are deleted by default
    • Specify that a file resource is not deleted
Plugins:new CleanWebpackPlugin({
      cleanOnceBeforeBuildPatterns: [* */ *, '! File name ']})]Copy the code

html-webpack-plugin: Package files are automatically imported into HTML

Description: Automatically generate index.html with entry file references

let HtmlwebpackPlugin = require("html-webpack-plugin");
/ / configuration
plugins: [
  new HTMLWebpackPlugin({
      template: 'HTML file address '.filename: 'Packed HTML file name'.title: 'Set the HTML file name'})]Copy the code

Configuration items:

  • template:HTMLAddress of the file
    • If not settemplate, thenwebpackOne is automatically generatedHTMLfile
  • filename: PackedHTMLThe file name
  • titleSet:HTML the file name
    • htmlThe template file needs to be set:
<%= htmlWebpackPlugin.options.title %>

<title>
     <%= htmlWebpackPlugin.options.title %>
</title>
Copy the code
  • hash:true“GiveCSS,JSFile SettingshashValue”
    • packagedHTMLIntroduced in the documentJSCSSWill addhashValues, such as:

    <script src="dist_index.js? fdfde3b822e33cb629a9"</script>

  • chunks: [index, other]: Specifies which template to importJS
    • Multi-entry packing:chunks:['index123','common']

mini-css-extract-plugin

We need to use the loader of this plug-in, add before csS-loader. We need to use the loader of this plug-in

let MiniCssExtractPlugin = require("mini-css-extract-plugin");
plugins: [
 new MiniCssExtractPlugin()
]
rules: [{test: '/.\css$/'.use: [
    MiniCssExtractPlugin.loader, 'css-loader']}]Copy the code
  • Configuration items
    • Filename: 'CSS /[CSS filename].css'

optimize-css-assets-webpack-plugin: CSS file compression CSS does not compress by default

  • Method of use
    • Introduction:let optimizationCssAssets = require('optimize-css-assets-webpack-plugin')
    • configuration
    Optimization: {minimizer: [new optimizationCssAssets()]}Copy the code

terser-webpack-plugin: Handle the problem that JS compression is not automatic after CSS compression

Terser is used to compress JS.

  • Introduction:let terserWebpackPlugin = require('terser-webpack-plugin')
  • configuration
Optimization: {minimizer: [
  	new terserWebpackPlugin()
  ]
}
Copy the code

webpack-manifest-plugin

Description: Display manifest file for production assets

optimize-css-assests-webpack-plugin

Description: Used to optimize or compress CSS resources

6. Common Loader

Common Loaders in the CSS

css-loader

Description: Load CSS, support modularity, compression, file import and other disadvantages: all THE CSS code is inserted into the JS code file optimization: use plug-in: mini-CSS -extract-plugin, single CSS into a file

style-loader

Description: The CSS code into JS, through the DOM to operate to load CSS

less-loader: handlinglessfile

Description: Compile LESS to CSS

file-loader

Description: To output a file to a folder and reference the output file with a relative URL in the code

url-loader

Description: Base64 injects the contents of a file into the code when the file is too small

  • url-loaderIs called by defaultfile-loaderI need to introduce these twoloader
  • To convert a file to a path, file-loader is called

Configuration item: Options

  • name[ext] : img / [name].
    • What was the original name, useloaderAnd then what is it calledfile-laoderThe configuration of the”
  • Limit: Limit file size
    • If the image is less than the set limit, it will be converted tobase64If greater than, it will be called by defaultfile-loader, becomes a path
    • Image transferbase64The advantages of
      • becomebase64The advantage is that it can be reducedHTTPrequest
      • Reduce server resource usage

postcss-loader: Auto addCSSThe prefix

Description: Compatible writing that can handle CSS

  • Dealing with the correspondingCSSBefore I file it, let’s addpostcss-loader
rules: [
  {test: '/.\css$/'.use: [
    MiniCssExtractPlugin.loader, 'css-loader'.'postcss-loader']}]Copy the code
  • configurationpostcss.config.js
    • Required installation: postCSs-preset -env
    • Create a file at the level of package.json: postcss.config.js “This file is the postCSS configuration file”
module.exports = {
  plugins: [
  	'post-preset-env']}Copy the code
  • Set the browser compatible version of “.browsersListtrc file”
    • Json file:.browserslisttrc “This file tells PostCSS to be browser-compatible”
    • Contents of the document:Cover 99.9%

Loader commonly used in JS

eslint-loader

Description: Checks JS code with ESlint

To deal withJSA high-level language is converted to a low-level language

  • Need to usebabel
    • babel-loader
    • @babel/core
    • @babel/preset-env
  • ES6The new syntax needs to be installed:@babel/plugin-syntax-class-propertiesPlug-ins to compile,babel-loaderNot currently supported
class A {
  constructor() {
     this.a=677; / / support
  }
  xxx=123;/ / does not support
}

Copy the code
  • Logger: Decorator, needs to be installed@babel/plugin-proposal-decoratorsThe plug-in
  • Async await, plug-ins to be installed:
    • @babel/plugin-transform-runtime

    • @babel/runtime/

    • @babel/runtime-corejs3

    • Configuration item: Corjs is the @babel/ Runtime-corejs3 core library. It can escape incompatible grammars into compatible grammars. The value is 3

  • babelpluginspresetThe difference between
    • presets: Default “collection of plug-ins”
    • presetsCan be used as ababelA combination of plugins, prepared in advance of the required plugins, if used locally, will not be put in the default
    • plugins: plugins, which we need to use, but are not included in the default
{
    test: /\.js$/,
    use: {
        loader: 'babel-loader'.options: {
            presets: ['@babel/preset-env'].plugins: [['@babel/plugin- proposal-decorators', {legacy: true}],
                  ['@babel/plugin- proposal-class-properties', {loose: true}],
                  ['@babel/plugin-transform-runtime', {corejs: 3}}, exclude: /node_modules/}// @babel/ plugin-proposal-class-properties and @babel/ plugin-proposal-class-properties exist together. Class - the properties later

Copy the code

7. Differences between Loader and Plugin

Loader

  • Loader is a converter. Webpack can only parse JS files, if you want to package other files, use Loader
  • What Loader does: Enables WebPack to load and parse non-JS files

Plugin

  • A Plugin is a plug-in. You can extend the functionality of WebPack to make it more flexible.

8. Webpack build process

  • Initialization parameters: get the parameters from the configuration file and the Shell statement “parameters passed when entering the command line: webpack –mode=development” read and merge the parameters to get the final parameters

  • Start compiling: initialize the Compiler object using the parameters obtained in the previous step, load all the configured plug-ins, and execute the object’s run method to start compiling. Locate all entry files according to the entry in the configuration

  • Compiling modules: Starting from the import file, all configured Loaders are called to compile the module, recursively query the modules that the module depends on, and then compile the module again until all import dependent files have been processed

  • Compile modules: after using the Loader after compiling all modules, each module was compiled which content and the dependencies between them, according to the entrance and the dependencies between modules, forming a contains more than one module of the Chunk, and then converts each Chunk into a separate file if to the list of output; This is your last chance to modify the output

  • Output complete: After determining the output content, determine the output path and file name based on the configuration, and write the output content to the file system

9. What is source Map? How to use the production environment?

  • Source Map is a technique that helps us debug the original development code when it is inconsistent with the actual running code
  • Webpack can be configured to automatically give us source Maps files, which are a way to correspond to compiled files and source files

Type of the source map

  • Source-map: raw code that generates a file in map format, code with mapping is “slow”
  • Eval-source-map: raw code that generates source-map with “highest execution and lowest performance”
  • Cheap-module-eval-source-map: Original code (only line information) “higher quality and lower performance”
  • Cheap -eval-source-map: conversion code (inside line) “can’t see the real source code”
  • Eval: generates code
  • Cheap -source-map: Conversion code (line information) is not mapped
  • Cheap-module-source-map: original code (line information only)

Can’t remember? Look at the following: Introduction of keywords

  • Eval: Wrap module code in eval
  • Source-map: generates the. Map file
  • Cheap: Does not contain column information
  • Module: contains Loader and source-map
  • Inline: The map is embedded as a DataURI and the map file is not generated separately

How to select the type of source-map

  • The column information in the source code is meaningless, as the line information completely establishes the dependencies between the pre-packaged and post-packaged code. Therefore, column information can be ignored in both development and production environments. Therefore, the cheap attribute can be ignored
  • You need to locate debug to the original source, not the compiled JS code. So, you can’t ignore the Module
  • The.map file needs to be generated, so the source-map attribute is required

Select type: development environment: cheap-module-eval-source-map Production environment: cheap-module-source-map

module.exports = {
  devtool: 'none'.// SourceMap
  entry: './src/index.js'.// Import file
  output: {
    filename: 'bundle.js'./ / file name
    path: path.resolve(__dirname, 'dist')  / / folder}}Copy the code

10. How can WEBpack be used to optimize front-end performance

Compression JS

new TerserPlugin()

Compress CSS

new OptimizeCssAssetsPlugin()

The compressed image

image-webpack-loader

Clear useless CSS

Extract CSS separately: mini-CSS-extract-plugin

loader: MiniCssExtractPlugin.loader

Copy the code

Purgecss-webpack-plugin: purgecss-webpack-plugin

new PurgecssPlugin({
// find all files in the SRC directory
 paths: glob.sync(`${PATHS.src}/ * * / * `, {nodir: true});
})
Copy the code

Tree Shaking

There are many methods in a module, and Tree Shaking is packaging only used methods, not used ones

module: {
	rules: [{
    	test: /\.js/,
        use: [{
        	loader: 'bable-loader'.options: {
            	presets: [['@babel/preset-env', {'modules': false}]]}}]}Copy the code

The code segment

Description: Divide the code into chunks and load them when the code runs until it needs them

Method of division:

  • Entry point segmentation: Configure multiple entry files in entry “for multi-page applications”

    • Disadvantages:
      • If the entry file contains duplicate modules, these modules are packaged into bundles
      • Inflexible, unable to split code dynamically
  • Dynamic import and lazy load

    Description: What function modules are required to load the corresponding code, also known as load on demand

    Usage: through the import keyword to achieve lazy loading module, encounter import will be code segmentation

    // The login module is loaded only after the click event is triggered
    root.addEventListener('click'.() = >{
        import('./login').then(result= >{
            console.log(result.data); })})Copy the code

    How to load on demand in React

    The Loading component is rendered before the Title component is rendered

    const App = React.lazy(() = >{
        // Lazy load the Title module
        import(/* webpackChunkName: 'title' */'./components/Title')})/ / render function
    render() {
        return (
            <>
                <Suspense fallback={<Loading />} ><Title />
                <Suspense/>
            </>)}Copy the code
  • Preload Preloads

    Description: Preload is usually used for key resources to be used on the page, including key JS, fonts, CSS, etc. Preload will put the download order of resources in the first place. “Asynchronous/lazy insertion scripts are low in network priority”, so that key resources can be downloaded in advance, which can optimize the page opening speed

    Usage: Adds a preloaded comment to the resource indicating that the module needs to be used immediately

    <link rel='preload' as='script' href='utils.js'>
    
    Copy the code
    import(
    `./utils.js`
    /*webpackPreload: true*/
    /*webpackChunkName: 'utils'*/
    )
    
    Copy the code
  • Prefetch Prefetch

    Description: Tell the browser that a resource is likely to be used in the future, and let the browser load the resource when it is free

    Method of use

    import(
    `./utils.js`
    /*webpackPrefetch: true*/
    /*webpackChunkName: 'utils'*/
    )
    
    Copy the code
  • Difference between preload and preFetch

    • Preload: tells the browser what resources the page must need and the browser must load those resources. “When the page must need resources, use preload.”
    • Prefetch: Tells the browser what resources the page may need, and the browser may not load these resources. “When the page may need resources, use Prefetch.”
  • Extract common code

    • Why extract?
      • A page contains a lot of common code, and code conflicts can occur if all of them are included
      • The same code is loaded repeatedly, wasting traffic to the user and cost to the server
      • Too many resources need to be loaded on each page. As a result, the first page load slowly, affecting user experience
      • If the common code is removed, creating a separate file for loading can be optimized, reducing network traffic and reducing server costs
    • How to extract?
      • Common code between pages, created separately as a file
      • Each page generates a separate file
      • Introduce public files on required pages
  • Code segmentation: splitChunks

    • This is a subcontracted configuration “taken out of node_modules and packaged to produce a separate file”
    • Module: Code introduced through import statements
    • Chunk: Webpack is split based on its features, including three scenarios
      • Your project entry
      • Dynamically imported code through import()
      • splitChunks
    • Bundle: Files packaged by webpack, usually in a one-to-one relationship with chunk. Bundles are files compiled, compressed, and packaged by chunk
    • The default configuration
      • CacheGroups: a package that meets these criteria and can be directly cached in the future. “Build once, use cache next time and beyond”
      • When an import is encountered, it is split, and the default is only asynchronous
    splitChunks: {
      chunks: 'all'.// All: all, initial: synchronous, async: asynchronous
      name: true.// The packaged name page1~page2.chunk.js
      minSize: 0.// Minimum size of code block. Default: 30KB
      minChunks: 1.// The number of times the module is referenced before splitting
      maxAsyncRequests: 2.// Maximum number of parallel requests per import()
      maxInitialRequests: 4 // The maximum number of splits per entry
      automaticNameDelimiter: '~'.// Split JS naming rule page1-page2.chunk.js
      cacheGroups: {
      	// Set the cache group to be used to extract chunks of different rules
        vendors: {
        	chunks: 'all'.test: /node_modules/./ / conditions
            priority: -10.// Priority. If a chunk meets multiple cache groups, it is split into the cache group with the highest priority
        },
        commons: {
        	chunks: 'all'.minSize: 0.// The minimum extraction size
            minChunks: 1.// Minimum number of chunks referenced
            priority: -20.reuseExistingChunk: true.// If the extracted chunk is referenced, refer to the chunk directly without repeating the packaging code}}}Copy the code
  • HASH

    • A unique hash value is generated each time a Webpack is built
    • All HASH Settings will share the same HASH value throughout the compilation process
    • If one value changes, all files will be regenerated with a new HASH value
    • Cache mode of file resources
      • Normally HTML is not cached
      • Third party library: strong cache
      • Other resource files: negotiated cache
      • To use caching properly, hash is configured, files are updated and repackaged, and original file resources are used if no updates are made
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: '[name].[hash].js'.chunkFilename: '[name].[hash].chunk.js'.publicPath: 'http://www.guyal.cn'
    }
    // MiniCssExtractPlugin: download by yourself
    plugins: [{
        new MiniCssExtractPlugin({
            filename: '[name].[hash].css'})}]Copy the code
  • ChunkHash: code block HASH

    • Generate hash values based on chunk. If they are from the same chunk, the hash values are the same
    • The HASH value is regenerated only when the module of the code block changes. Otherwise, the HASH value does not change
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: '[name].[chunkhash].js'.chunkFilename: '[name].[chunkhash].chunk.js'
    }
    // MiniCssExtractPlugin: download by yourself
    plugins: [{
        new MiniCssExtractPlugin({
            filename: '[name].[chunkhash].css'})}]Copy the code
  • ContentHash: code block HASH

    • Hash file generated based on the content
    • If the file contents are the same, the HASH value is the same
    • The HASH value changes only when the content changes
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: '[name].[contenthash].js'.chunkFilename: '[name].[contenthash].chunk.js'
    }
    // MiniCssExtractPlugin: download by yourself
    plugins: [{
        new MiniCssExtractPlugin({
            filename: '[name].[contenthash].css'})}]Copy the code

11. How to speed up webPack construction

  • Package speed analysis plugin: speed-measure-webpack-plugin
  • Optimization scheme
    • Extensions: You can omit file extensions when importing files. Use more in the front, less in the back
    resolve: {
    	extensions: ['.js'.'.jsx'.'.json'.'.css']}Copy the code
    • Alias: Configure an alias for an absolute path to speed up module search.
    resolve: {
      alias: {
         The '@': path.resolve(__dirname, '.. /src')}}Copy the code
    • Externals: external extension

      • To extract the package used in the project from the package file, we need to configure externals to achieve this, and use CDN to import jQuery in HTML

      • The packing volume is reduced and the packing speed is accelerated

      • configuration

      externals: {
          "jQuery"."jQuery"
      }
      Copy the code
      • Introduction:import $ from 'jQuery'
    • ProvidePlugin: WebPack comes with a plug-in

      • This configuration allows us to eliminate the need to introduce:import xxx from "xxx", directly use the corresponding variables
       webpack.ProvidePlugin({
          "Name of variable to use in file":"Name of the package installed"
      })
      Copy the code

      Configure the plug-in

      plugins: [
        new webpack.ProvidePlugin({
           '$': 'jQuery'.'$$': 'jQuery'})].externals: {
          "jQuery""JQuery"},Copy the code
    • resolve.alias

      • Configuring an alias for an absolute path can speed up module search
      resolve.alias = {
          'xxx': 'Absolute path to XXX'
      }
      Copy the code
      • configuration
      resolve: {
        alias: {
           The '@': path.resolve(__dirname, '.. /src')}}Copy the code
      • The introduction ofimport xxx from '@/index'

      advantages

      • Can speed up the search for files
      • Increase build speed
    • resolve.modules

      • If no relative path file is written, go firstsrcIf not, gonode_modulesLook for
      • Configuration:
      resolve.modules = [path.resolve(__dirname, 'src'), 'node_modules']
      Copy the code
    • module.noParse

      • Explicitly tell Webpack that these packages do not depend on any other packages
      • configuration
      module: {
        noParse: /jQuery|lodash/
      }
      Copy the code
    • DefinePlugin “Define global variables”

      • Defines global variables that are added at compile time
      • configuration
      webpack.DefinePlugin({
          xxx: JSON.stringify("xxx")})Copy the code
      new webpack.DefinePlugin({
      	BASEURL: "https://baidu.com"
      })
      // BASEURL is a variable that needs to be converted to a string:
      / / JSON. Stringify (" https://baidu.com "),
      // Output: "https://baidu.com"
      Copy the code
    • thread-loader

      • The happypack package I used before is no longer maintained.
      • configuration
      module: {
       rules: [{test: /\.js$/,
              include: path.resolve('src'),
              use: [
                 "babel-loader"."thread-loader"]]}}Copy the code

      Advantages: Can improve the construction speed; “@vue/cli create-react-app is built in, we don’t need to configure it normally.”

    • ignorePlugin

      • When packaging, ignore the specified file “you know what package won’t work”
      • For example, the language switch package: moment
        • Install: YARN add moment
          • Language switch packages, however: all language packages will be installed
        • Reference:new webpack.IgnorePlugin(/local/, /moment/)
          • When packing, ignore the local file under moment
        • What packages to import with what packages:import 'moment/locale/zh-cn'

        advantages: Reduce the volume after packaging

    • Using the cache

      • Babel-loader: enables cache
        • Cache the result of babel-loader execution and read the cache during rebuild to improve packaging speed
        {
        	test: /\.js$/,
            use: [{
            	loader: 'babel-loader'}}]Copy the code
      • cache-loader
        • Add cache-loader before the performance-consuming loader and cache the result to disk
        {
        	test: /\.js$/,
            use: ['cache-laoder'. loaders] }Copy the code