1. 程式人生 > >習慣用腳手架的你, 瞭解Webpack這些知識點嗎?

習慣用腳手架的你, 瞭解Webpack這些知識點嗎?

大概準備春招兩個月了, 也沒找到坑位埋自己, 來看看webpack

webpack

官網: www.webpackjs.com

對於前端的大兄弟來說, 每天在前端摸爬滾打, 各方征戰, 那對於webpack肯定再熟悉不過了

所以說這篇文章適合給像我們這樣的後端的同胞看著玩,(一說前端不是想用BootStrap就想用其他前端框架的UI元件庫, 要不就是vue的腳手架) , 那對於浪跡各大vue react元件庫的你, 對於喜歡用腳手架構建專案的你, 對於喜歡一鍵打包專案的你, 真的瞭解webpack各種目錄和預設配置嗎?

webpack的核心概念:

  • 入口: 從哪裡開始打包
  • 出口: 打包的結果輸出到哪裡去
  • loader: 我們通過npm給webpack安裝上不同的loader, webpack就能處理不同格式的檔案, 用於處理圖片等靜態資源的loader, 處理css的loader, 處理less的loader, 用於適配各種瀏覽器的loader等等
  • 外掛: 作用於整個打包過程, 比如用於本件拷貝的外掛, 用於生成html的外掛, 用於處理css的外掛

搭建一個空的專案

通過這個小案例你將瞭解:

  • 區域性安裝webpack-cli的命令是什麼 ?
  • 如何在新專案中使用區域性安裝的webpack ?
  • webpack的預設啟動目錄, 啟動檔案在哪裡 ? 叫什麼 ?
  • 什麼是mode? (development production)
  • 有哪些build mode , 這些mode有何區別 ?

繼續:

命令: npm init 建立一個空專案

執行完成後, 會為我們生成一個packetage.json檔案

然後安裝webpack 包管理工具命令: npm i webpack-cli -D

注意點:上面的安裝命令是區域性安裝命令,  如果我們進入這個專案中, 使用npm run build命令嘗試將這個專案打包時, 會報錯 說 missing script : build

解決方法: 在package.json的script部分中加入下面的配置 後, 再使用 npm run build 命令時, 會自動使用我們在區域性安裝的這個命令

--mode 指定在什麼環境下打包, 上面的 production 就是說打包後在生產環境下使用, 和development最直接的不同點就是 前者會將main.js 壓縮

繼續執行npm run build 命令: 會遇到新的錯誤, 說解析不到 src目錄, 原因是webpack找到不到入口目錄

預設的, webpack的入口會去找 src/index.js

我們在根目錄下將這個目錄創建出來, 再次執行npm run build 即可打包成功, 打包的結果: /dist/main.js , 會將專案中依賴的js檔案, 打包成一個js檔案

npm run xxx ,命令中的xxx就是上圖中的srcipt中定義的 比如npm run dev , npm run build , npm run start , npm run test

webpack的配置檔案

看完這本小節你將瞭解:

  • webpack預設的配置檔案叫什麼 ?
  • webpack預設的配置檔案在哪裡 ?
  • 如何修改webpack預設配置檔案所在的路徑和名稱 ?
  • webpack的入口js檔案可以修改嗎? 如何修改 ?
  • webpack的配置檔案中output目錄及檔案可以修改嗎? 如何修改 ?
  • output輸出的目標檔案預設叫什麼名? 可以修改嗎?
  • webpack有哪些hash函式可以使用 ?

ok, 繼續:

  • 有哪些預設的配置?

webpack.config.js, 預設的webpack會去根目錄中尋找他, (如過我們把它放在自定義的目錄中, webpack是找不到它的)

但是可以在 package.json中去修改這個預設的配置, 如下: 新增--config 引數

  • 能新增哪些自定義的配置?

webpack.config.js 配置檔案的作用的對外暴露node.js的配置指令碼, 看下圖, 可以知道, webpack.config.js中對應的就是webpack對應的各個模組的

參照這個連線: https://www.webpackjs.com/concepts/configuration/

用大白話說, webpack.config.js 可以告訴webpack打包的mode, 是否需要壓縮, 入口js檔案在哪裡, 打包結果輸出到什麼目錄, 輸出結果叫什麼, 等等

var path = require('path');
module.exports = {
    mode: 'development', // 指定打包後在什麼環境下使用
    entry: './src/index.js', // 指定入口js檔案, todo 可以在這裡修改入口js檔案
    output: {
        path: path.resolve(__dirname, 'dist'), // 打包後的檔案所在的目錄名
        //filename: 'foo.bundle.js' // 打包後生成的檔名, 預設是main.js

        // hash值是通過入口目錄中的入口js算出來的, 一旦js改變, 每次build的結果的hash值
        //filename: '[name].[hash].js' // 生成的檔名: main.e9bsajdoahsds.js
        //filename: '[name].[hash:6].js' // 生成的檔名: main.6位長度hash值.js
        filename: '[name].[chunkHash:6].js' // 生成的檔名: main.6位長度hash值.js  且共存多個模組時, 只有那個發生變動的入口js對應生成的 output檔名中的js雜湊值才會改變

        // 第三種hash contenthash ,是根據檔案的內容計算出來的hash
    }
};
  • webpack的三種hash值
    • hash: 它是工程級別的, 即修改工程中任何一個檔案, 整個工程的檔案快取都會失效, 打包出來的檔案的hash值都會發生改變, 缺點: 如果專案存在多個入口, 勢必針對每一個入口js檔案都打包出來一個帶有hash值的結果檔案, 雖然是兩個不同的入口, 但是屬於一個工程, 所有多個目標檔案的hash值都會改變
    • chunkHash: 它解決了hash的缺點帶來的不足條件, 還是同一個專案,多個入口js的情況, 使用chunkHash模式, 然後修改一個入口js的內容, 打包出來的結果檔案中, 只有被修改了的那個js的hash改變;
    • contentHash: 根據檔案的內容計算hash

打包後自動生成html

學完本節你將瞭解

  1. 如何讓webpack打包出一個單頁index.html
  2. 如何讓webpack基於我們自己提供的html頁面生成 index.html

參考連結: https://www.npmjs.com/package/html-webpack-plugin

預設的, webpack會將專案中依賴的js檔案打包稱一個js檔案輸出到 / dist / 目錄中, 但是不會為我們生成html檔案, 這時候我們需要手動的將生成的js檔案引入到我們自己的index.html檔案中, 這樣整挺麻煩的

所有, 一般我們會這麼搞, 把自己的index.html檔案放在/public/index.html中, 然後安裝webpack的外掛, 讓這個外掛替我們完成上面的那個複雜的過程, 如下

安裝命令:

npm i --save-dev html-webpack-plugin

參考: webpack.config.js

const HtmlWebpackPlugin = require('html-webpack-plugin')
 
module.exports = {
  entry: 'index.js',
  output: {
    path: __dirname + '/dist',
    filename: 'index_bundle.js'
  },
 // 著重看一下這個plugin模組   
 plugins: [
    new HtmlWebpackPlugin(), // Generates default index.html
    new HtmlWebpackPlugin({  // Also generate a test.html
      filename: 'test.html',
      // 允許使用者自定義一個html模板, webpack會在這個模板上累加上自己生成的js  
      template: 'src/assets/test.html'
    })
  ]
}

引入CSS

看完本節你將瞭解:

  1. 兩種方式讓webpack替我們匯入css檔案

參考連結: https://www.npmjs.com/package/css-loader

  • 第一種方式:

安裝loader外掛命令

npm i style-loader -D
npm install --save-dev css-loader

參考配置檔案 : 通過一個rules來控制這個過程, 通過正則匹配到css, 然後對這些匹配到的檔案使用 style-loader css-loader , 執行的順序的 後面的css-loader比style-loader先執行

module.exports = {
  module: {
    rules: [
      { 
        test: /\.css$/i,
        use: ['style-loader', 'css-loader'],
      },
    ],
  },
};

通過如下方式將css引入

此時再執行 npm run build 可以完成構建工作

問題來了, 通過這種方式匯入進來的css檔案在哪裡呢?

通過檢視html原始碼可見, 構建出來的原始碼被放在head標籤中


  • 第二種引入css檔案的方式, 將css匯入進來, 並提取成一個獨立的檔案, 並自動插入到html中

參考連結: https://www.npmjs.com/package/mini-css-extract-plugin

安裝命令:

npm install --save-dev mini-css-extract-plugin

參考webpack.config.js

const MiniCssExtractPlugin = require('mini-css-extract-plugin');
 
module.exports = {
  // 在plugins部分new出來
  plugins: [
    new MiniCssExtractPlugin(
     {
        filename: '[name].[chunkHash:8].css'
      }
  )],
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: [
          {
            loader: MiniCssExtractPlugin.loader,
            options: {
              esModule: true,
            },
          },
          'css-loader',
        ],
      },
    ],
  },
};

這種方式生成結果如下:

很明顯: css被新增在head標籤中, script新增在index.html末尾

小技巧, 如果想讓生成的檔案呈現下面的樣子:

可以在webpack.config.js檔案中, 使用下面的方式為檔案命名

new MiniCssExtractPlugin(
            {
                filename: 'css/[name].[chunkHash:8].css'
            }
   )

CSS預處理

參考連結: https://www.npmjs.com/package/less-loader

目的是處理less, 將less轉換成css

安裝 less 和 less-loader

 npm install less less-loader --save-dev

在webpack.config.js中新增less的解析規則

loader的第二種寫法

        {
                test: /\.less$/i,
                use: [
                    MiniCssExtractPlugin.loader,
                    'css-loader',
                   // 'less-loader',
                    {
                        loader: "less-loader",
                        options:{
                            
                        }
                    }
                ],
            }

自動新增CSS字首

看完本節你將瞭解

  1. 啥是css3字首
  2. 為啥要加字首
  3. 怎麼通過webpack新增字首

那為啥要新增字首呢?

因為在CSS標準未被確定之前, 市面上的不同瀏覽器使用自己私有的字首卻分不同的CSS樣式, 當標準確定之後, 各大瀏覽器不再使用這些字首, 目前很多私有的字首都可以不再寫了, 但是為了相容, 可以仍然使用字首逐漸過度

常見的瀏覽器的字首如:

  1. Chrome谷歌瀏覽器: -webkit-
  2. Safari蘋果瀏覽器: -webkit-
  3. FireFox 火狐: -moz-
  4. IE: -ms-
  5. Opera 歐朋瀏覽器: -O-

例:

#example{
    -webkit-outline: none;
    -moz-outline: none;
    -ms-outline: none;
    -o-outline: none;
    -khtml-outline: none;
    outline: none;
}

如何配置webpack, 自動新增瀏覽器css3字首

參考連結: https://www.npmjs.com/package/autoprefixer

安裝命令:

npm i postcss-loader autoprefixer -D

第二步: 在專案的根目錄下建立 postcss.config.js 配置檔案

postcss的npm包參考連結: https://www.npmjs.com/package/postcss

 module.exports = {
  plugins: [
      // 他需要下面的外掛 autoprefixer
    require('autoprefixer'),
  ]
}

第三步: 在webpack.config.js配置檔案中新增指定的postcss-loader, 注意把他的新增順序, 放在靠前的位置

第四步: 在package.json配置檔案中新增 browerslist相關配置, 可以針對不同瀏覽器做出更詳細的配置

參考連結: https://www.npmjs.com/package/browserslist

例項:

 "browserslist": [
    "defaults",
    "not IE 11",
    "not IE_Mob 11",
    "maintained node versions",
  ]

並不是瀏覽器包含的越多越好, 比如說想用ES5的話, IE的版本至少要大於等於8

處理資原始檔

看完本節, 你將瞭解:

  1. 三種處理資原始檔的方式
  • 第一種處理方式 file-loader

使用file-loader處理資原始檔, 參考連結 <https://www.npmjs.com/package/file-loader >

安裝命令: 

npm install file-loader --save-dev 

參照上面連結中的示例配置, 為webpack.config.js中新增file-loader相關的模組

示例:

  rules: [           
          {
                test: /\.(png|jpe?g|gif)$/i,
                use: [
                    {
                        loader: 'file-loader',
                        options:{
                            // 指定webpack打包後, 輸出的路徑
                            name: 'static/images/[name].[ext]',
                            // 這個publicPath規定的路徑, 就是webpack執行專案後, 所有的資原始檔url的最前面的公共部分
                            publicPath: '/',
                        }
                    },
                ],
            }
      ]

注意點: 如果不新增publicPath的話, 將出現下面的問題

  • 第二種處理方式

參考連結: https://www.npmjs.com/package/url-loader

url-loader的優點, 會針對不同圖片做不同的壓縮

安裝命令

npm install url-loader --save-dev

同樣是在webpack.config.js中新增配置

   {
                test: /\.(png|jpg|gif)$/i,
                use: [
                    {
                        loader: 'url-loader',
                        options: {
                            // url-loader和file-loader的工作原理相似, 當資源的大小小於limit指定的值時, 資源將被替換成base64編碼的資料植入html或者 css中
                            limit: 80,
                            name: 'static/images/[name].[ext]',
                            // 這個publicPath規定的路徑, 就是webpack執行專案後, 所有的資原始檔url的最前面的公共部分
                            publicPath: '/',
                        },
                    },
                ],
            }

url-loader的特點如下:

  1. 當資源size < limit值時, 將使用base64對資源進行加密處理
  2. 當資源size > limit值時, 和file-loader相似, 將圖片本身輸出到指定的目錄中
  • 第三種處理方式

比如專案中引用了字型檔案, 直接寫死在index.html模板中, 而不需要使用file-loader或者url-loader進行壓縮之類webpack的處理和生成的操作, 那麼可以使用下面的外掛, 直接進行檔案的copy

參考連結: https://www.npmjs.com/package/copy-webpack-plugin

命令:

npm install url-loader --save-dev

參考webpack.config.js如下:

const CopyPlugin = require('copy-webpack-plugin');
 
module.exports = {
  plugins: [
       new CopyPlugin([
            {   // 將專案根路徑下的static目錄中的內容, 拷貝到dist/static/images中
                from: path.resolve(process.cwd(),'static/'),
                to: path.resolve(process.cwd(),'dist/static/images中')
            },
        ]),
  ],
};

新增Babel-loader

為什麼要使用babel-loader?

我們都是到, 瀏覽器只認識html css 原生js , 後續js發展的很快, ES5 ES6出世了, 但是不少瀏覽器根本不支援ES6的語法, 比如 import export 物件/函式 等等

如何使用?

參考連結: https://www.npmjs.com/package/babel-loader

安裝命令:

npm install -D babel-loader @babel/core @babel/preset-env webpack

示例:

rules: [
  // the 'transform-runtime' plugin tells Babel to
  // require the runtime instead of inlining it.
  {
    test: /\.m?js$/,
    exclude: /(node_modules|bower_components)/,
    use: {
      loader: 'babel-loader',
      options: {
        presets: ['@babel/preset-env'],
        plugins: ['@babel/plugin-transform-runtime']
      }
    }
  }
]

webpack讓前端專案獨立佔用一個埠執行

通過這小節你將知道:

  1. webpack 通過什麼讓前端專案獨立執行
  2. 如何安裝這個外掛
  3. 如何配置進webpack, 讓webpack使用它
  4. 在那個配置檔案中對devs-server進行更多的配置

參考連線: https://www.npmjs.com/package/webpack-dev-server

安裝命令:

npm install webpack-dev-server --save-dev 

修改npm的配置檔案, 新增dev選項

這也就是為啥, 通過腳手架構建的開發環境, 能npm run dev執行起來

並且, 專案執行起來後, 我們做出的任何修改, 都會熱載入進來, 時時更新, 無須重啟

在webpack.config.js中新增devServer模組

如:

一般在開發時. 這個配置肯定是需要定製的, 如果在這裡模擬前後端聯調, 就在這個模組配置mock資料的地址

 devServer: {
   change xxx-api/login => mock/login
    detail: https://cli.vuejs.org/config/#devserver-proxy
  },

或者是真的在前後端聯調, 因為埠不同將出現跨域, 在這裡配置代理伺服器的地址

// 參考: https://www.webpackjs.com/configuration/dev-server/#devserver-proxy
devServer: {
   proxy: 'http://localhost:8089'
},

比如, 自動開啟啊等等, 更多的配置 參考連結 https://www.webpackjs.com/configuration/dev-server/