preface

Componentization, modularization, automation and engineering are now one of the criteria for assessing whether a front-end project is an excellent project. Thus, a series of front-end modularization and engineering tool libraries emerged. Babel and Webpack are great examples. Do you know them? Do you know how to optimize front-end projects with Babel and Webpack?

The body of the

webpack

Webpack is a front-end building tool whose main function is to package and integrate various modules with dependencies to generate static resources. Like the picture on the website:

Module Chunk Bundle

  • Module: each source file, webpack all modules
  • Chunk: a file composed by multiple modules. Entry, import(), splitChunk can be used to generate chunk
  • Bundle: The final output file is called the bundle

The difference between loader and plugin

  • Loader: module converter. less=>css
  • Plugin: Extension plug-in

Webpack performance optimization

Basically divided into two aspects:

  • Optimize packaging build speed
  • Optimized output code

Optimize packaging build speed

Optimization of Babel – loader

  • Enable the cacheuse:['babel-loader?cacheDirectory]
  • Use include and exclude wisely

IgnorePlugin: Ignores localized content

new Webpack.IgnorePlugin(/\.\/locale/./moment/),//moment references to the./locale/ directory are ignored and not packaged

// index.js needs to manually import the required parts of the current package into the file
import moment from 'moment'
// Manually import the required language packs
import 'moment/locale/zh-cn';
moment.locale('zh-cn');
Copy the code

NoParse: Packages are packaged without resolving whether there are dependencies on other packages in the relevant modules, and there are no dependencies in these tripartite libraries

module: {noParse:/jquery|lodash/.// Do not parse the dependent libraries in jquery and Lodash
}
Copy the code

HappyPack: Enable multi-process packaging to speed up builds.

  // loader
{
  text:/\.js$/,
  use:['happypack/loader? id=babel'],}// plugins
new HappyPack({
    id:'babel'.loaders: [{loader: 'babel-loader'.options: {cacheDirectory: true,}}})Copy the code

parallelUglifyPlugin

  • Webpack has a built-in Uglify tool to compress JS, but it cannot open multiple processes
  • The project is relatively large. Multiple processes are needed only when the build speed is slow. Simply enabling multiple processes on a project is too expensive and may slow down the packaging process
new ParallelUglifyPlugin({
  uglifyJS: {output: {
      beautify: false.// Compact output
      comments:false.// Delete comments
    },
    compress: {drop_console: true.collapse_vars: true.// Inline variables that are defined but used only once
      reduce_vars: true.// Extract static values that occur multiple times but are not defined as variables to reference}}}),Copy the code

Automatic refresh:watch: true

Hot update:HotModuleReplacementPlugin

Js files need to be manually configured to achieve hot update. CSS changes are automatically hot updated.

DllPlugin: Dynamic link library

  • First use webpack.dllplugin to package the DLL. js file and mainfest.json
entry:{
  vendors: ['lodash'].react: ['react'.'react-dom'],},output: {filename:'[name].dll.js'.path: path.resolve(__dirname,'.. /dll'),
  library: '[name]',},plugins: [
  new webpack.DllPlugin({
    name: '[name]'.path: path.resolve(__dirname,'.. /dll/[name].manifest.json')})]Copy the code
  • . Then, once the run dev used when webpack DllReferencePlugin associated documents, use AddAssetHtmlWebpackPlugin in HTML to add the DLLS. Js file reference
const files = fs.readdirSync(path.resolve(__dirname,'.. /dll'))
files.forEach(file= > {
  if(/.*\.dll.js/.test(file)){
    plugins.push(
      new AddAssetHtmlWebpackPlugin({
        filepath: path.resolve(__dirname, '.. /dll', file)
      }),
    )
  }
  if(/.*\.manifest.json/.test(file)){
    new webpack.DllReferencePlugin({
      manifest: path.resolve(__dirname, '.. /dll', file)
    })
  }
})
Copy the code
  • Not recommended in production environments

Optimized output code

The code is smaller

  • Enable code compression
module.exports = {
  optimization: {
    minimize: true.minimizer: [
      new TerserPlugin({
        exclude: /\/node_modules/,
  	  parallel: true.// Enable multi-threaded compression})],}};Copy the code
  • Url-loader outputs base64 images
  • Tree-Shaking: mode: 'production'
    • Tree-shaking is only possible using ES Module references
  • Scope Hosting: smaller code size, less Scope to create functions, more readable code
    // ES6 modularity files pointed out in jsNext :main are preferred for NPM third-party modules
    resolve: ['jsnext:main'.'browser'.'main'].plugin: {// Start Scope Hosting
      new webpack.optimize.ModuleConcatenationPlugin()
    }
    Copy the code

Reasonable subcontracting, no repeated loading

  • The packaged bundle plus the Hash, unchanged file to hit the cache
  • Extract common code:
optimizatoin:{
  splitChunks: {chunks: 'all'.minSize: 20000.// The minimum size, in bytes, of the generated block.
    maxSize: 0.minChunks: 1.// How many times does the code have to be introduced before the code is separated
    maxAsyncRequests: 6.// Maximum number of simultaneous requests when loading on demand
    maxInitialRequests: 4.// The maximum number of parallel requests at the entry point.
    automaticNameDelimiter: '~'.cacheGroups: {
      vendors: {
        test: /[\\/]node_modules[\\/]/,
        priority: -10./ / priority
      },
      default: {
        minChunks: 2.priority: -20.reuseExistingChunk: true // If the current block contains a module that has been split out of the main bundle, it will be reused instead of generating new modules. This may affect the resulting file name of the block.}}}},Copy the code

Faster and less memory usage

  • Using lazy loadingimport()
  • Using CDN acceleration:publicPath:'http://cnd.com'

babel

Babel is a JavaScript compiler. He is responsible for

  • Check whether the syntax complies with es5 syntax specifications. If not, switch
  • Not handling modularity (Webpack handling)

presets

Presets are the default components in Babel. It’s a collection of plugins. Common are

  • @babel/preset-env
  • @babel/preset-flow
  • @babel/preset-react
  • @babel/preset-typescript

babel-polyfill

  • core-js: a tool library for converting ES6 and ES7 codes into ES5 codes
  • regeneratorWill:generatorA library of tools for converting functions to ES5 code

Babel-polyfill is the set of both. Babel dropped babel-Polyfill in version 7.4 and recommends that users use core-JS or ReGenerator directly

How do I implement on-demand references under the.babelrc file

{
  "presets":[
    [
      "@babel/preset-env",
      {
        "useBuiltIns": "usage".// Reference as needed
        "corejs": 3./ / core - js version
        "regenerator": true,}]]}Copy the code

babel-runtime

Babel-polyfill causes global contamination, and runtime is designed to prevent global contamination. This can be used when writing third-party libraries.

.babelrc

{
  "plugins":[
    [
      "@babel/plugin-transform-runtime",
      {
        "absoluteRuntime": false."corejs": false."helpers": true."regenerator": true."useESModules": false,}]]}Copy the code

Why is the front end packaged and built?

  • Smaller (tree-shaking, compression, merging) and faster to load
  • Compile high-level languages and syntax (TS, ES6+, modular, SASS, less)
  • Compatibility and syntax checking (Polyfill, PostCSS, ESLint)
  • Unify the development environment of universities
  • Unified build process and output standards
  • Integrated company construction specification (test and launch)

Follow public account

Like the students can pay attention to the public account