1. 程式人生 > 實用技巧 >webpack配置詳解

webpack配置詳解

目錄

Entry

1.單入口:字串

entry: './src/index.js'

打包形成一個chunk,輸出一個bundle檔案

2.多入口:字串陣列

entry: ['./src/index.js', './src/count.js']

所有入口最終只會形成一個chunk,且只輸出一個bundle檔案

3.多入口:物件

entry: {
    index: ['./src/index.js', './src/count.js'], 
    add: './src/add.js'
  }

有幾個(鍵值對)檔案入口就形成幾個chunk,輸出幾個bundle檔案,此時chunk名稱==鍵名,可在dll中使用

Output

output: {
    // 檔名稱(指定名稱+目錄)
    filename: '[name].js',
    // 輸出檔案目錄(將來所有輸出資源的公共目錄)
    path: resolve(__dirname, 'build'),
    // 所有輸出資源引入公共路徑字首 -- 'imgs/a.jpg'-->'/imgs/a.jpg'
    // 一般用於生產環境
    publicPath: '/',
    // 非入口chunk的名稱(import,optimization--node_modules)
    chunkFilename: '[name]_chunk.js',
    /* dll */
    library: '[name]', //整個庫向外暴露的變數名
    libraryTarget: 'window' //變數名新增到哪個上 browser 
    // libraryTarget: 'global' //變數名新增到哪個上 node 
    // libraryTarget: 'commonjs' //用commonjs語法 
  }

其中library屬性,以用dll技術打包jquery庫為例

module.exports = {
  entry: {
    // 最終打包生成[name] --> jquery
    // ['jquery'] --> 要打包的庫是jquery
    jquery: ['jquery']
  },
  output: {
    filename: '[name].js',
    path:resolve(__dirname, 'dll'),
    library: '[name]_[hash]' //打包庫裡向外暴露出去的內容叫什麼名字
  },
  plugins: [
    new webpack.DllPlugin({
      name: '[name]_[hash]', //對映庫的暴露內容名稱
      path: resolve(__dirname, 'dll/manifest.json') //輸出檔案路徑
    })
  ]
}

Module

module: {
    rules: [
      // loader
      {
        test: /\.css$/,
        // 多個loader用use
        use: ['style-loader', 'css-loader']
      },
      {
        test: /\.js$/,
        // 排除node_modules下的js檔案
        exclude: /node_modules/,
        // 只檢查src下的js檔案
        include: resolve(__dirname, 'src'),
        // 優先、延後執行
        enforce: 'pre', //'post'
        // 單個loader用loader
        loader: 'eslint-loader',
        options: {} //loader的配置
      },
      {
        // 以下配置只會生效一個
        oneOf: []
      }
    ]
  },

DevServer

devServer: {
    // 構建後的專案路徑,執行程式碼的目錄
    contentBase: resolve(__dirname,'build'),
    // 監視contentBase目錄下的所有檔案,一旦檔案變化就會reload
    watchContentBase: true,
    watchOptions: {
      // 忽略檔案
      ignored: /node_modules/
    }
    //啟動gzip壓縮
    compress: true,
    // 埠號
    port: 5000,
    // 自動開啟覽器
    open: true,
    // 域名
    host: 'localhost',
    // 開啟HMR功能
    hot: true,
    // 不顯示啟動伺服器日誌資訊
    clientLogLevel: 'none',
    // 除了一些基本的啟動資訊外,其他內容不要顯示
    quiet: true,
    // 如果出錯了,不要進行全屏顯示
    overlay: false,
    // 伺服器代理 -- 解決開發環境跨域問題
    proxy: {
      // 一旦DevServer(5000)伺服器接收到/api/xxx的請求,就會把請求轉發到另一個伺服器(3000)
      '/api': {
        target: 'http://localhost:3000',
        // 傳送請求時,請求路徑重寫:將/api/xxx --- /xxx (去掉api)
        pathRewrite: {
          '^/api': ''
        }
      }
    }
  }

Resolve

module.exports = {
  entry: './src/js/index.js',
  output: {
    filename: '[name].js',
    path: resolve(__dirname, 'build'),
  },
  module: {
    rules: [
      // loader
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader']
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin()
  ],
  mode: 'development',
  // 解析模組的規則
  resolve: {
    // 配置解析模組的路徑別名,可以簡寫路徑,但是寫路徑時沒有提示
    alias: {
      $css: resolve(__dirname, 'src/css')
    },
    // 配置省略檔案路徑字尾名
    // extensions: ['css', 'jsx'],
    // 告訴webpack解析模組式去哪個找目錄
    modules: [resolve(__dirname, '../../node_modules')]
  }
}

Optimization

optimization中的一些預設值:

optimization: {
    splitChunks: {
      chunks: 'all',
      /* 以下都是預設值,可以不寫 */
      minSize: 30 * 1024, //分割的chunk最小為30kb
      maxSize: 0, //最大沒有限制
      minChunk: 1, //要提取的chunk最少被引用一次
      maxAsyncRequests: 5, //按需載入時並行載入的檔案數量
      maxInitialRequests: 3, //入口js檔案最大並行請求數量
      automaticNameDelimiter: '~', //名稱連線符
      name: true, //可用命名規則
      cacheGroups: {//分割chunk的組
        // node_modules檔案會被打包到vendors組的chunk中 -- vendors~xxx.js
        // 滿足上面的公共規則,如:大小超過30kb,至少被引用一次
        vendors: {
          test: /[\\/]node_modules[\\/]/,
          // 優先順序
          priority: -10
        },
        default: {
          // 要提取的chunk最少被引用兩次
          minChunks: 2,
          // 優先順序
          priority: -20,
          // 如果當前要打包的模組,和之前已經被提取的模組式同一個,就會複用,而不是重新打包模組
          reuseExistingChunk: true
        }
      }
    },

其他配置:

optimization: {
     splitChunks: {
       chunks: 'all',
    // 將當前模組的記錄其他模組的hash單獨打包為一個檔案runtime
    // 解決:修改a檔案導致b檔案的contenthash變化
    runtimeChunk: {
      name: entrypoint => `runtime-${entrypoint.name}`
    },
    minimizer: {
      // 配置生產環境的壓縮方案:js,css
      new TerserWebpackPlugin({
        // 開啟快取
        cache: true,
        // 開啟多程序打包
        paraller: true,
        // 啟動source-map
        sourceMap: true
      })
    }
  }

optimization只在production模式下使用