1. 程式人生 > >webpack學習(十二):多頁面提取公共部分(js&css)

webpack學習(十二):多頁面提取公共部分(js&css)

demo地址: https://github.com/Lkkkkkkg/webpack-demo
繼上一次配置完多頁面 : https://blog.csdn.net/qq593249106/article/details/84933978

使用SplitChunksPlugin

The CommonsChunkPlugin 已經從 webpack v4 legato 中移除, webpack 4+ 版本使用內建的 SplitChunksPlugin 外掛來進行公共部分的提取:

配置 webpack.config.js

因為 SplitChunksPlugin 是 webpack 4+ 版本內建的外掛, 所以無需安裝, 只需在 webpack.config.js 中配置

optimization: {
        splitChunks: {
            cacheGroups: {
                //打包公共模組
                commons: {
                    chunks: 'initial', //initial表示提取入口檔案的公共部分
                    minChunks: 2, //表示提取公共部分最少的檔案數
                    minSize: 0, //表示提取公共部分最小的大小
                    name: 'commons'
//提取出來的檔案命名 } } } }

注意

還要在每一個頁面的 HtmlWebpackPlugin 的 chunks 加上 commons, 因為提取之後的 commons 需要被打包出來的頁面引用!

webpack.config.js

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin'
); const MiniCssExtractPlugin = require("mini-css-extract-plugin"); var devMode = false; //標誌是否開發模式 const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin'); module.exports = { mode: 'development', entry: { //入口檔案 index: "./src/components/index/index.js", otherA: "./src/components/otherA/otherA.js", otherB: "./src/components/otherB/otherB.js", }, output: { path: path.join(__dirname, 'dist'), filename: 'js/[name].js', //根據入口檔案分為不同出口檔案 }, devtool: 'inline-source-map', // 不同選項適用於不同環境 devServer: { contentBase: './dist', //將dist目錄下的檔案(index.html)作為可訪問檔案, 如果不寫這個引數則預設與webpack.cofig.js的同級目錄 port: 8080 //埠號設為8080, 預設也是8080 }, module: { rules: [ //配置載入器, 用來處理原始檔, 可以把es6, jsx等轉換成js, sass, less等轉換成css { exclude: /node_modules|packages/, //路徑 test: /\.js$/, //配置要處理的檔案格式,一般使用正則表示式匹配 use: 'babel-loader', //使用的載入器名稱 }, { test: /\.(sa|sc|c)ss$/, use: [ devMode ? 'style-loader' : MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader', ], }, ] }, plugins: [ //webpack 通過 plugins 實現各種功能, 比如 html-webpack-plugin 使用模版生成 html 檔案 new CleanWebpackPlugin(['dist']), //設定清除的目錄 new HtmlWebpackPlugin({ template: "./src/components/index/index.html", //設定生成的HTML檔案的名稱, 支援指定子目錄,如:assets/admin.html chunks: ['index', 'commons'], //指定入口檔案 filename: "index.html" //指定模板檔案的位置 }), new HtmlWebpackPlugin({ template: "./src/components/otherA/otherA.html", chunks: ['otherA', 'commons'], filename: "otherA.html" }), new HtmlWebpackPlugin({ template: "./src/components/otherB/otherB.html", chunks: ['otherB', 'commons'], filename: "otherB.html" }), new MiniCssExtractPlugin({ filename: 'css/[name].css', //類似出口檔案 chunkFilename: 'css/[id].css' }), new OptimizeCssAssetsPlugin({ assetNameRegExp: /\.css$/g, //一個正則表示式,指示應優化\最小化的資產的名稱。提供的正則表示式針對配置中ExtractTextPlugin例項匯出的檔案的檔名執行,而不是源CSS檔案的檔名。預設為/\.css$/g cssProcessor: require('cssnano'), //用於優化\最小化CSS的CSS處理器,預設為cssnano。這應該是一個跟隨cssnano.process介面的函式(接收CSS和選項引數並返回一個Promise)。 cssProcessorOptions: { safe: true, discardComments: { removeAll: true } }, //傳遞給cssProcessor的選項,預設為{} canPrint: true //一個布林值,指示外掛是否可以將訊息列印到控制檯,預設為true }) ], optimization: { splitChunks: { cacheGroups: { //打包公共模組 commons: { chunks: 'initial', //initial表示提取入口檔案的公共部分 minChunks: 2, //表示提取公共部分最少的檔案數 minSize: 0, //表示提取公共部分最小的大小 name: 'commons' //提取出來的檔案命名 } } } } };

這裡修改一下目錄結構, 在 src 新建一個 common 資料夾, common 資料夾下新建一個 css 資料夾, 專門用來放公共的 css 檔案, 新建一個 common.scss 放入 css 資料夾中, 測試能否打包這個公共的 scss:
common.scss

$fontSize: 100px;

h1 {
  font-size: $fontSize;
}
|- /dist
  |- /css //分離出來的css檔案
     |- index.css 
     |- otherA.css 
     |- otherB.css 
  |- /js
     |- index.js
     |- otherA.js
     |- otherB.js
  |- index.html
  |- otherA.html
  |- otherB.html
|- /node_modules
|- /src //用於放原始檔的資料夾
  |- common //存放公共檔案的目錄
    |- css // 存放公共css的目錄
      |- common.scss //公共css
   |- components //存放頁面的目錄
    |- index //主頁
      |- App.js
      |- index.html 
      |- index.js
      |- index.scss
    |- otherA //另一個頁面A
      |- App.js
      |- otherA.html 
      |- otherA.js
      |- otherA.scss
    |- otherB //另一個頁面B
      |- App.js
      |- otherB.html 
      |- otherB.js
      |- otherB.scss
|- package.json
|- webpack.config.js //webpack配置檔案

修改一下 index.js, otherA.js, otherB.js, 讓它們都引入公共樣式 common.scss:
index.js

import React from 'react'
import { render } from 'react-dom'
import App from './App'
import './index.scss'
import '../../common/common.scss'

render(<App />, document.getElementById("root"))

otherA.js

import React from 'react'
import { render } from 'react-dom'
import App from './App'
import './otherA.scss'
import '../../common/css/common.scss'

render(<App />, document.getElementById("root"))

otherB.js

import React from 'react'
import { render } from 'react-dom'
import App from './App'
import './otherB.scss'
import '../../common/css/common.scss'

render(<App />, document.getElementById("root"))

打包

終端輸入 npm run build, 發現 dist 目錄下的 css 和 js 資料夾分別多了 commons.css 和 commons.js, 而且其他 css 和 js 檔案大小都變小了

|- /dist
  |- /css //分離出來的css檔案
     |- commons.css 
     |- index.css 
     |- otherA.css 
     |- otherB.css 
  |- /js
     |- commons.js
     |- index.js
     |- otherA.js
     |- otherB.js
  |- index.html
  |- otherA.html
  |- otherB.html
|- /node_modules
|- /src //用於放原始檔的資料夾
  |- common //存放公共檔案的目錄
    |- css // 存放公共css的目錄
      |- common.scss //公共css
   |- components //存放頁面的目錄
    |- index //主頁
      |- App.js
      |- index.html 
      |- index.js
      |- index.scss
    |- otherA //另一個頁面A
      |- App.js
      |- otherA.html 
      |- otherA.js
      |- otherA.scss
    |- otherB //另一個頁面B
      |- App.js
      |- otherB.html 
      |- otherB.js
      |- otherB.scss
|- package.json
|- webpack.config.js //webpack配置檔案

開啟 index.html, otherA.html, otherB.html:
在這裡插入圖片描述
在這裡插入圖片描述
在這裡插入圖片描述
公共樣式 h1{font-size:100px} 起了效果, 提取公共 js&css成功