webpack初識

一、什麼是Webpack

WebPack能夠看作是模塊打包機:它作的事情是,分析你的項目結構,找到JavaScript模塊以及其它的一些瀏覽器不能直接運行的拓展語言(Scss,TypeScript等),並將其打包爲合適的格式以供瀏覽器使用。在3.0出現後,Webpack還肩負起了優化項目的責任。css

這段話有三個重點:前端

  • 打包:能夠把多個Javascript文件打包成一個文件,減小服務器壓力和下載帶寬。
  • 轉換:把拓展語言轉換成爲普通的JavaScript,讓瀏覽器順利運行。
  • 優化:前端變的愈來愈複雜後,性能也會遇到問題,而WebPack也開始肩負起了優化和提高性能的責任。

二、爲什要使用WebPack

現在的不少網頁其實能夠看作是功能豐富的應用,它們擁有着複雜的JavaScript代碼和一大堆依賴包。爲了簡化開發的複雜度,前端社區涌現出了不少好的實踐方法react

a:模塊化,讓咱們能夠把複雜的程序細化爲小的文件;webpack

b:相似於TypeScript這種在JavaScript基礎上拓展的開發語言:使咱們可以實現目前版本的JavaScript不能直接使用的特性,而且以後還能轉換爲JavaScript文件使瀏覽器能夠識別;web

c:scss,less等CSS預處理器json

 

 

tree shaking 是一個術語,一般用於描述移除 JavaScript 上下文中的未引用代碼(dead-code)。它依賴於瀏覽器

  • ES2015 模塊語法(import和export)
  • 在項目 package.json 文件中,添加一個 "sideEffects" 入口。
  • 引入一個可以刪除未引用代碼(dead code)的壓縮工具(minifier)(例如 UglifyJSPlugin, babel-minify-webpack-plugin, webpack-closure-compiler);或者將mode設成production。

將文件標記爲無反作用(side-effect-free)緩存

這種方式是經過 package.json 的 "sideEffects" 屬性來實現的.服務器

{
  "name": "your-project",
  "sideEffects": [
    "./src/some-side-effectful-file.js",
    "*.css"
  ]
}

壓縮輸出:從 webpack 4 開始,能夠經過 "mode" 配置選項設置爲 "production",輕鬆實現壓縮輸出。babel

webpack.config.js

const path = require('path');

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist')
    },
 mode: "production"
};

 devtool:   開發環境下使用inline-source-map,生產環境使用source-map.

Code spliting(代碼分離)

1.手動添加入口起點

2.移除重複的依賴模塊:(webpack4取消了CommonsChunkPlugin),轉而使用下面的方法。

optimization與entry/plugins同級
optimization: {  // 優化
    splitChunks: {  // 分離
      cacheGroups: {
        commons: {
          name: 'common',   // 共享模塊的名稱
          chunks: 'initial',  //
          minChunks: 2  // 公享模塊最少複用過幾回
        }
      }
    }
  }

 3.動態導入  import()

async function getComponent () {
       const _ = await import(/* webpackChunkName: "lodash" */ 'lodash');
       var element = document.createElement('div');
       element.innerHTML = _.join(['hello', 'webpack'], ' ');
       return element;
 }

 

緩存:確保 webpack 編譯生成的文件可以被客戶端緩存,而在文件內容變化後,可以請求到新的文件。

1.使用 [chunkhash] 生成文件名

output: {
    filename: '[name].[chunkhash].js',
    path: path.resolve(__dirname, 'dist')
  },

2. 代碼分離:optimization.splitChunks在每次修改後的構建結果中,將 webpack 的樣板(boilerplate)和 manifest 提取出來。

此外,將第三方庫(library)(例如 lodashreact)提取到單獨的 vendor chunk 文件中。

 

entry: {
    app: './src/script/index.js',
    vendor: ['lodash']
  },
optimization: {  // 優化
      splitChunks: {  // 分離
        cacheGroups: {
          vendor: {
            name: 'vendor',
            priority: 10,
            chunks: 'initial',  //
            // enforce: true
          },
          commons: {
            name: 'manifest',   // 共享模塊的名稱
            chunks: 'initial',  //
            minChunks: 1  // 公享模塊最少複用過幾回
          }
        }
    }
}    

注意問題:

 1.混合使用ES2015,AMD CommonJS

你能夠自由混合使用三種模塊類型(甚至在同一個文件中)。在這個狀況中 webpack 的行爲和 babel一致。

// ES2015 模塊調用 CommonJS
import fs from "fs"; // module.exports 映射到 default
import { readFileSync } from "fs"; // 從返回對象(returned object+)中讀取命名的導出方法(named exports)

typeof fs.readFileSync === "function";
typeof readFileSync === "function";

須要讓 Babel 不解析這些模塊符號,從而讓 webpack 可使用它們。能夠經過設置以下配置到 .babelrc

{
  "presets": [
    ["@babel/preset-env", {"modules": false}],
  ]
}

2.只在production環境下才會用到的工具(在development時應避免)

  • UglifyJsPlugin
  • ExtractTextPlugin
  • [hash]/[chunkhash]
  • AggressiveSplittingPlugin
  • AggressiveMergingPlugin
  • ModuleConcatenationPlugin
相關文章
相關標籤/搜索