使用webpack4.x定製自己的前端開發環境

論前端搬磚工的自我修養發表於2019-04-28

一,最基礎的環境

1,初始化環境

     yarn init (npm init)
複製程式碼

2,安裝webpack webpack-cli

說明webpack-cli 在4.0版本已經脫離了webpack 需要單獨按照,個人建議最好把按照包安裝在專案環境裡,這樣可以確保整個專案用的版本一樣
複製程式碼

      yarn add webpack

      yarn add webpack-cli
複製程式碼

3,在package.json 新增script

"scripts": { "build": "webpack --mode production" }

4,我們在專案目錄下新增一個檔案src/index.js

(這是webpack預設的入口檔案)

5,執行命令

yarn run dev
複製程式碼

6, webpack.config.js的基本內容

const path = require('path')
const UglifyPlugin = require('uglifyjs-webpack-plugin')

module.exports = {
    entry: './src/index.js',

    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'bundle.js',
    },

    module: {
        rules: [
            {
                test: /\.js$/,
                loader: 'babel-loader',
                include: [path.resolve(__dirname, 'src')]
            },
        ],
    },

    // 程式碼模組路徑解析的配置
    resolve: {
        modules: [
            "node_modules",
            path.resolve(__dirname, 'src')
        ],

        extensions: [".wasm", ".mjs", ".js", ".json", ".jsx"],
    },

    plugins: [
        new UglifyPlugin(),
        // 使用 uglifyjs-webpack-plugin 來壓縮 JS 程式碼
        // 如果你留意了我們一開始直接使用 webpack 構建的結果,你會發現預設已經使用了 JS 程式碼壓縮的外掛
        // 這其實也是我們命令中的 --mode production 的效果,後續的小節會介紹 webpack 的 mode 引數
    ],
}
複製程式碼

基本解析:

使用webpack4.x定製自己的前端開發環境

注意:loader 和plugins都需要單獨安裝, 安裝到 devDependencies 因為這些外掛都只是構建程式碼時候有用

二,常用plugins

1,UglifyPlugin

這個用來進行js程式碼壓縮

yarn add uglifyjs-webpack-plugin --dev
複製程式碼

2,html-webpack-plugin

這個使用者把打包好的js檔案動態插入到index.html 預設入口檔案為根目錄下index.html 出口檔案預設為dist目錄下index.tml

  yarn add uglifyjs-webpack-plugin --dev
複製程式碼

使用webpack4.x定製自己的前端開發環境

也允許自己定義

module.exports = {
  // ...
  plugins: [
    new HtmlWebpackPlugin({
      filename: 'index.html', // 配置輸出檔名和路徑
      template: 'assets/index.html', // 配置檔案模板
    }),
  ],
}
複製程式碼

⚠️為什麼需要這個外掛?為什麼要動態插入? 主要是因為我們進行打包 為了防止瀏覽器快取,往往需要給打包出來到檔案新增[hash]。 所以就需要動態插入

3,extract-text-webpack-plugin@next

如果只用 css-loader & style-loader來轉換程式碼,css會程式設計js程式碼動態插入到html中 如果想把css單獨成一個檔案,就需要使用這個plugin

使用webpack4.x定製自己的前端開發環境

4,DefinePlugin

DefinePlugin 是 webpack 內建的外掛,可以使用 webpack.DefinePlugin 直接獲取。

這個外掛用於建立一些在編譯時可以配置的全域性常量,這些常量的值我們可以在 webpack 的配置中去指定,例如:

5,copy-webpack-plugin

我們一般會把開發的所有原始碼和資原始檔放在 src/ 目錄下,構建的時候產出一個 build/ 目錄,通常會直接拿 build 中的所有檔案來發布。有些檔案沒經過 webpack 處理,但是我們希望它們也能出現在 build 目錄下,這時就可以使用 CopyWebpackPlugin 來處理了。

一般開發時,會在根目錄下static目錄直接拷貝過去

new CopyWebpackPlugin([
  {
    from: path.resolve(__dirname, '../static'),
    to: 'static',
    ignore: ['.*']
  }
])
yarn add copy-webpack-plugin -D
複製程式碼

使用webpack4.x定製自己的前端開發環境

6,ProvidePlugin

ProvidePlugin 也是一個 webpack 內建的外掛,我們可以直接使用 webpack.ProvidePlugin 來獲取。

該元件用於引用某些模組作為應用執行時的變數,從而不必每次都用 require 或者 import,其用法相對簡單:

new webpack.ProvidePlugin({
  identifier: 'module',
  // ...
})

// 或者
new webpack.ProvidePlugin({
  identifier: ['module', 'property'], // 即引用 module 下的 property,類似 import { property } from 'module'
  // ...
})
複製程式碼

在你的程式碼中,當 identifier 被當作未賦值的變數時,module 就會被自動載入了,而 identifier 這個變數即 module 對外暴露的內容。

注意,如果是 ES 的 default export,那麼你需要指定模組的 default 屬性:identifier: ['module', 'default'],。

7,IgnorePlugin

IgnorePlugin 和 ProvidePlugin 一樣,也是一個 webpack 內建的外掛,可以直接使用 webpack.IgnorePlugin 來獲取。

這個外掛用於忽略某些特定的模組,讓 webpack 不把這些指定的模組打包進去。例如我們使用 moment.js,直接引用後,裡邊有大量的 i18n 的程式碼,導致最後打包出來的檔案比較大,而實際場景並不需要這些 i18n 的程式碼,這時我們可以使用 IgnorePlugin 來忽略掉這些程式碼檔案,配置如下

module.exports = {
  // ...
  plugins: [
    new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)
  ]
}
複製程式碼

8,optimize-css-assets-webpack-plugin

css 程式碼壓縮

const optimizeCss = require('optimize-css-assets-webpack-plugin');
plugins: [
    new optimizeCss()
]


yarn add  optimize-css-assets-webpack-plugin -D
複製程式碼

三,常用loaders

1,babel-loader

這個loader可以把es6 + 程式碼轉換為es5到程式碼。因為瀏覽器對於es6的程式碼相容不好,但是es6很多新語法對於我們開發工作提升很高。所以需要把 es6程式碼做轉換。

   yarn add babel-loader  @babel/core --dev
複製程式碼

2,css-loader & style-loader

css-loader 負責解析 CSS 程式碼,主要是為了處理 CSS 中的依賴,例如 @import 和 url() 等引用外部檔案的宣告; style-loader 會將 css-loader 解析的結果轉變成 JS 程式碼,執行時動態插入 style 標籤來讓 CSS 程式碼生效。

{
    test: /\.css/,
    include: [
        path.resolve(__dirname, 'src'),
    ],
    use: [
        'style-loader',
        'css-loader',
    ],
}
複製程式碼

注意:['style-loader','css-loader']這裡的配置是有順序的,但規則應用順序是從右到左的。也就是先 css-loader,再style-loader

  yarn add css-loader style-loader --dev

複製程式碼

segmentfault.com/a/119000001…

3,less-loader

css 預編譯器

module.exports = {
  // ...
  module: {
    rules: [
      {
        test: /\.less$/,
        // 因為這個外掛需要干涉模組轉換的內容,所以需要使用它對應的 loader
        use: ExtractTextPlugin.extract({ 
          fallback: 'style-loader',
          use: [
            'css-loader', 
            'less-loader',
          ],
        }), 
      },
    ],
  },
  // ...
}

yarn add less less-loader -D
複製程式碼

4,file-loader & url-loader & image-webpack-loader

file-loader 可以用於處理圖片檔案

{
    test: /\.(png|jpg|gif)$/,
    use: [
        {
            loader: 'file-loader',
            options: {},
        },
    ],
}

yarn add file-loader -D
複製程式碼

使用webpack4.x定製自己的前端開發環境

簡答地說,url-loader封裝了file-loader。url-loader不依賴於file-loader,即使用url-loader時,只需要安裝url-loader即可,不需要安裝file-loader,因為url-loader內建了file-loader。

通過上面的介紹,我們可以看到,url-loader工作分兩種情況:

1)檔案大小小於limit引數,url-loader將會把檔案轉為DataURL;

2)檔案大小大於limit,url-loader會呼叫file-loader進行處理,引數也會直接傳給file-loader。因此我們只需要安裝url-loader即可。

url-loader

{
  test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
  loader: 'url-loader',
  query: {
    limit: 10000,
    name: utils.assetsPath('img/[name].[hash:7].[ext]')
  }
},
{
  test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
  loader: 'url-loader',
  query: {
    limit: 10000,
    name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
  }
}

yarn add url-loader -D
複製程式碼

使用webpack4.x定製自己的前端開發環境

image-webpack-loader可以用來做圖片壓縮

{
            loader: 'image-webpack-loader',
            options: {
              mozjpeg: { // 壓縮 jpeg 的配置
                progressive: true,
                quality: 65
              },
              optipng: { // 使用 imagemin-optipng 壓縮 png,enable: false 為關閉
                enabled: false,
              },
              pngquant: { // 使用 imagemin-pngquant 壓縮 png
                quality: '65-90',
                speed: 4
              },
              gifsicle: { // 壓縮 gif 的配置
                interlaced: false,
              },
              webp: { // 開啟 webp,會把 jpg 和 png 圖片壓縮為 webp 格式
                quality: 75
              },
          }
yarn add image-webpack-loader

複製程式碼

5,NamedModulesPlugin(), && HotModuleReplacementPlugin()

熱模組替換相關

plugins: [ // ... new webpack.NamedModulesPlugin(), // 用於啟動 HMR 時可以顯示模組的相對路徑 new webpack.HotModuleReplacementPlugin(), // Hot Module Replacement 的外掛 ],

四, 本地伺服器 webpack-dev-server & webpack-dev-middleware

1, webpack-dev-server使用

新增script

"start": "webpack-dev-server --mode development"
複製程式碼

new webpack.NamedModulesPlugin(), // 用於啟動 HMR 時可以顯示模組的相對路徑 new webpack.HotModuleReplacementPlugin(), // Hot Module Replacement 的外掛

webpack-dev-server當更多配置檢視https://webpack.docschina.org/configuration/dev-server/

yarn add webpack-dev-server -D

2 ,webpack-dev-middleware使用

我們也可以使用webpack-dev-middleware 來啟動靜態伺服器 使用如下 首先安裝 webpack-dev-middleware 依賴:

npm install webpack-dev-middleware --save-dev
複製程式碼

接著建立一個 Node.js 服務的指令碼檔案,如 app.js:

const webpack = require('webpack')
const middleware = require('webpack-dev-middleware')
const webpackOptions = require('./webpack.config.js') // webpack
複製程式碼

配置檔案的路徑

// 本地的開發環境預設就是使用 development mode

webpackOptions.mode = 'development'
const compiler = webpack(webpackOptions)
const express = require('express')
const app = express()

app.use(middleware(compiler, {
  // webpack-dev-middleware 的配置選項
}))

// 其他 Web 服務中介軟體
// app.use(...)

app.listen(3000, () => console.log('Example app listening on port 3000!'))
複製程式碼

新增script

"start": "node app.js"
複製程式碼

五,配置拆分

webpack.base.js:基礎部分,即多個檔案中共享的配置 webpack.development.js:開發環境使用的配置 webpack.production.js:生產環境使用的配置 因此,只要有一個工具能比較智慧地合併多個配置物件,我們就可以很輕鬆地拆分 webpack 配置,然後通過判斷環境變數,使用工具將對應環境的多個配置物件整合後提供給 webpack 使用。這個工具就是 webpack-merge。

相關文章