By chance, I read Su Shi’s Ode to The Red Cliff. And high school to read completely different, perhaps on the age, experienced a few years of working people’s bitterness, suddenly succumbed to Su Shi’s open-minded, there is a kind of enlightened comfort, paste some famous sentences, and your mutual mian.

The deceased so, and did not taste also; The surplus and deficiency are like that, and the pawn does not rise and fall. Cover will see it from its change, then heaven and earth could not in a moment; Since its invariable person and view, then the thing and I are endless also, and what envy! And between heaven and earth, everything has its own owner, if not my own, though not a penny and do not take. However, the breeze on the river and the moon on the mountain, the ear gets the sound, the eye meets the color, take no ban, inexhaustible. It is the infinite hiding place of the creator, and the place where I and the son live together. —– Ode to the Red Cliff

— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — I am a line — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —

modular

  • Improve work efficiency and reduce maintenance costs

First, modular evolution

  • File partitioning (globally introduced in Script)
    • Bureau of Global Effects on Pollution
    • Naming conflicts
    • Dependencies between modules cannot be resolved
  • Namespace approach (globally introducing different namespaces)
  • IIFE (Execute functions now)
    • Ensure the security of private Spaces

Second, modular specification

The CommonJS specification loads modules in synchronous mode

  • A file is a module
  • Each module has a separate scope
  • Exports members through modele.exports
  • Load the module via the require function

AMD (Asynchronous Module Definition Specification) — CommonJS for require.js nodes and ES Modules for browsers

ES Modules (The most mainstream front-end specification standard)

By adding a type = model attribute to the script tag, you can execute the JS code in ES Module standards

1. Basic features

  • The ESM automatically adopts strict mode, ignoring ‘Use strict’
  • Each ES Module runs in its own private scope
  • ESM makes external JS requests via CORS (the environment that requires the request supports cross-domain)
  • The ESM script tag delays the execution of the script

2. Import and export ES Module

Var name = '11 export {name} export default {name} import {name} from "index.js" console.log(name) var name = '11 export {name} export default {name} //'11' import {default as data} from "index.js" console.log(data.name)Copy the code
  • Export followed by {} is a fixed syntax. It does not guide to an object. When referencing an object, it points to the address of the memory space
  • The exported objects are read-only and cannot be modified

3, ES Modules in node.js

  • CommonJS modules can be imported into ES Module
  • CommonJS cannot import ES Module modules
  • CommonJS always exports only one default member
  • Note that import is not a deconstructed export object,
//module.mjs var foo = '2', bar = '55' export { foo, Bar} / / -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - / / common. Js. Exports = {foo: {module.exports = {foo: 'common js', } exports.foo = 'commonjs2' exports is an alias of module.exports //--------------------------------------------------------------------------------------- //index.mjs import { foo, bar } from './module.mjs' console.log(foo, bar) import fs from 'fs' fs.writeFileSync('./foo,txt', 'es modlue working') import { writeFileSync } from 'fs' writeFileSync('./bar.txt', '111222') import mod from './common.js' console.log(mod)Copy the code

4. Differences between ES Modlue and CommonJS

  • ESM no longer has CommonJS module members (require, module, exports, __filename, __dirname)
  • Add the type:’modlue’ attribute to package.json to use ESM directly in JS files, rather than in MJS files. In this case, the CommonJS file needs to be renamed to.cjs
  • Run the ESM file node –experimental-modules index.js
Import {fileURLToPath} from 'url' import {dirname, firname} from 'path' const __filename = fileURLToPath(import.meta.url) const __dirname = dirname(__filename)Copy the code

Four, Webpack packaging

1, the Loader

The default entry file is SRC /index.js, and the input path is dist/main.js

Loader is a core feature of WebPack, with which you can load any type of resource

Loader is responsible for converting resource files from input to output. The same resource file can depend on multiple Loaders

Because of the need for module packaging, import and export are handled and other ES6 features in the code cannot be converted. Webpack loader classification

  • Compiler conversion class
  • File manipulation class
  • Code inspection class
//webpack.config.js const path = require('path') module.exports = {//yarn webpack --mode development Webpack --mode None Mode: 'None ', entry: './ SRC /main. CSS ', // custom entry file output: {filename: 'index.js', // Output file name path: Path. join(__dirname, 'dist'), // Output folder name, path is absolute}, //yarn add css-loader --dev Handle the CSS module //yarn add style-loader --dev append the result of css-loader to the page with style tags module: {rules: [ { test: /.css$/, use: ['style-loader', 'css-loader'], // If multiple loaders are configured, //yarn add file-loader --dev //yarn add url-loader --dev can convert images to base64 // small files using Data URLs, {test: /.jpg$/, // use: 'file-loader', use: {loader: 'url-loader', Options: {limit: 10 * 1024, // base64},},},],},}Copy the code

yarn add babel-loader @babel/core @babel/preset-env –dev

Webpack is just a packaging tool

The loader can be used to compile the transformation code

Module: {rules: [{test: /.js$/, use: {// Replace the default loader, can handle js new features: ['@babel/preset-env'], }, }, }, ] }Copy the code

How the Webpack module is loaded

  • Follow the ES Module standard import statement
  • Follow the CommonJS standard require function
  • Follow AMD standard define function and require function
  • The @import directive and URL function in the style code
  • The SRC attribute of the image tag in HTML code

2, the Plugin

Automatically clear the output directory

yarn add clean-webpack-plugin html-webpack-plugin copy-webpack-plugin –dev

const { CleanWebpackPlugin } = require('clean-webpack-plugin') const HtmlWebpackPlugin = require('html-webpack-plugin') const CopyWebpackPlugin = require('copy-webpack-plugin') module.exports = { mode: 'none', entry: './src/index.js', output: { filename: 'index.js', path: path.join(__dirname, 'dist'), publicPath: 'dist/', }, module: { rules: [ { test: /.js$/, use: { loader: 'babel-loader', options: { presets: ['@babel/preset-env'], }, }, }, { test: /. CSS $/, use: ['style-loader', 'css-loader'],}, {test: /.jpg$/, use: {loader: 'url-loader', options: { limit: 10 * 1024, }, }, }, { test: /.html$/, use: { loader: 'html-loader', options: { attrs: : [' img SRC ', 'a: href'],},},},],}, plugins plugins / / c: [new CleanWebpackPlugin(), // Generate index.html file new HtmlWebpackPlugin({title: 'Webpack Plugin Sample', meta: { viewport: 'width=device-width', }, template: './src/index.html', }), //about.html new HtmlWebpackPlugin({ filename: 'about.html', // specify the output filename template: './ SRC /index.html',}), // Copy the new CopyWebpackPlugin directly from the public directory ({patterns: [{the from: path. Join (__dirname, 'public'), / / need to copy the folder to: 'static', / / copy the name of the file under the dist},],}),],}Copy the code

3. Development of plug-ins

Plugin must be either a function or an object containing the Apply method that extends by mounting the function in the dog that declares the period

// Define a comment to delete bundle.js class MyPlugin {apply(compiler) {console.log('MyPlugin starts ') compiler.hooks. Emit. Tap ('MyPlugin', (in all engineering projects) => {// in all engineering projects => console.log() for (const name in all engineering projects) {// console.log(name) // console.log(compiliation.assets[name].source()) if (name.endsWith('.js')) { const contents = compiliation.assets[name].source() const withoutComments = contents.replace(/\/\*\*+\*\//g, '') compiliation.assets[name] = { source: () => withoutComments, size: () => withoutComments.length, } } } }) } }Copy the code

4. Enhance the webpack development experience

Watch Working mode: YARN webpack — Watch Automatic browser refresh: Brewer-sync

5. Webpack Dev Server

  • Integrated features such as automatic compilation and automatic browser refresh
  • Static resources require additional contentBase configuration
  • Set up proxy apis to resolve cross-domain issues
devServer: { contentBase: './public', proxy: { '/api': { //http://localhost:8080/api/users => https://api.github.com/api/users target: 'https://api.github.com', //http://localhost:8080/api/users => https://api.github.com/users pathRewrite: { '^/api': }, // You cannot use locahost:8080 as the host name for requesting Github.Copy the code

6. SourceMap(SourceMap)

Fixed source code and running code inconsistency issues

7. Devtool mode comparison

  • Eval – Whether to use EVAL to execute module code
  • Cheap -Source Map contains row information
  • Module – Whether you can get the source code before Loader processing

Select the appropriate Source Map first

  • Development mode: cheap-module-eval-source-map
    • Each line of code contains no more than 80 characters
    • The code after Loader conversion is quite different
    • The first packaging speed is slower, rewrite packaging speed is faster
  • Production environment: None (nosource-source-map)
    • The Source Map exposes the Source code
    • Debugging is a development phase thing

7. Module hot Update (HMR)

One of the most powerful features of WebPack is that it keeps code blocks up to date without a page refresh

  • The HMR in Webpack needs to handle module hot replacement logic manually
  • Style files are available out of the box because they are processed by the Loader
  • Projects created through scaffolding are internally integrated with HMR solutions
//webpack.config.js const webpack = require('webpack') devServer: { hot: true, }, plugins: [new webpack HotModuleReplacementPlugin ()], / / manually js hot replacement. / / the main js. / heading need to monitor module. The module hot. Accept ('/heading ', () => {console.log(' Heading module updated, need to manually replace hot update logic ')})Copy the code

8. Production environment optimization

  • Configuration files export different configurations based on different environments
  • Each environment corresponds to a configuration file
//webpack.config.js module.exports = (env, argv) => { const config = { mode: 'development', entry: './src/main.js', output: { filename: 'js/bundle.js', }, devtool: 'cheap-eval-module-source-map', devServer: { hot: true, contentBase: 'public', }, module: { rules: [ { test: /\.css$/, use: ['style-loader', 'css-loader'], }, { tets: /\.(png|jpe?g|gif)$/, use: { loader: 'file-loader', options: { outputPath: 'img', name: '[name].[ext]', }, }, }, ], }, plugins: [ new HtmlWebpackPlugin({ title: 'Webpack Tutorial', template: './src/inedx.html', }), new webpack.HotModuleReplacementPlugin(), ], } if (env === 'production') { config.mode = 'production' config.devtool = false config.plugins = { ... config.plugins, new CleanWebpackPlugin(), new CopyWebpackPlugin(['public']) } } return config }Copy the code
yarn webpack --dev production
Copy the code

9. The abnormal environment corresponds to different configuration files

// run yarn webpack --config webpack.prod.js // or add the command to scripts const common = Reuqire ('./webpack.common.js') // Public configuration const merge = require('webpack-merge') const {CleanWebpackPlugin} = requre('clean-webpack-plugin') const CopyWebpackPlugin = require('copy-webpack-plugin') module.exports = merge(common, { mode: 'production', plugins: [new CleanWebpackPlugin(), new CopyWebpackPlugin(['public'])], })Copy the code

10, Tree – Shaking

  • Unreferenced code is automatically removed from the code and is automatically enabled in production mode.
  • Tree Shaking uses the ES Module
  • Something in Babel converts ES Module to CommonJS, and Tree Shaking is broken
/ / manual open optimization: {usedExports: true, / / which is cited part of the code concatenateModules: true, / / as far as possible to incorporate all modules into a function of export, improve operational efficiency, Minimize code size :true // compress results},Copy the code

11. Multi-entry packing

entrry:{ index:'./src/main.js', album:'./src/ablum.js' }, Optimization :{splitChunks:{chunks:'all'}}, plugins: [new HtmlWebpackPlugin({title: 'Multi Entry', template: './src/inedx.html', filname:'index.html', chunks:['index'] }), new HtmlWebpackPlugin({ title: 'Multi Entry', template: './src/album.html', filname:'album.html', chunks:['album'] }), ]Copy the code

12, hash value

  • Hash: whole project level (every file has the same hash value)
  • Chunkhash: The hash value of an entry file is changed (each chunkhas the same hash value).
  • Contenthash: The hash value changes when a file changes