webpack 我的筆記

webpack快速入門教程

測試文檔見github 記得star 哦

1、了解Webpack相關

  • 什么是webpack
    • Webpack是一個模塊打包器(bundler)。
    • 在Webpack看來, 前端的所有資源文件(js/json/css/img/less/...)都會作為模塊處理
    • 它將根據(jù)模塊的依賴關系進行靜態(tài)分析,生成對應的靜態(tài)資源
  • 五個核心概念
    • Entry:入口起點(entry point)指示 webpack 應該使用哪個模塊,來作為構建其內部依賴圖的開始。
    • Output:output 屬性告訴 webpack 在哪里輸出它所創(chuàng)建的 bundles,以及如何命名這些文件,默認值為 ./dist。
    • Loader:loader 讓 webpack 能夠去處理那些非 JavaScript 文件(webpack 自身只能解析 JavaScript)。
    • Plugins:插件則可以用于執(zhí)行范圍更廣的任務。插件的范圍包括,從打包優(yōu)化和壓縮,一直到重新定義環(huán)境中的變量等。
    • Mode:模式,有生產模式production和開發(fā)模式development
  • 理解Loader
    • Webpack 本身只能加載JS/JSON模塊,如果要加載其他類型的文件(模塊),就需要使用對應的loader 進行轉換/加載
    • Loader 本身也是運行在 node.js 環(huán)境中的 JavaScript 模塊
    • 它本身是一個函數(shù),接受源文件作為參數(shù),返回轉換的結果
    • loader 一般以 xxx-loader 的方式命名,xxx 代表了這個 loader 要做的轉換功能,比如 json-loader。
  • 理解Plugins
    • 插件可以完成一些loader不能完成的功能。
    • 插件的使用一般是在 webpack 的配置信息 plugins 選項中指定。
  • 配置文件(默認)
    • webpack.config.js : 是一個node模塊,返回一個 json 格式的配置信息對象

2、開啟項目

  • 初始化項目:

    • 生成package.json文件

      {
        "name": "webpack_test",
        "version": "1.0.0"
      } 
      
  • 安裝webpack

    • npm install webpack webpack-cli -g //全局安裝,作為指令使用
    • npm install webpack webpack-cli -D //本地安裝,作為本地依賴使用

3、編譯打包應用

  • 創(chuàng)建js文件
    • src/js/app.js
    • src/js/module1.js
    • src/js/module2.js
    • src/js/module3.js
  • 創(chuàng)建json文件
    • src/json/data.json
  • 創(chuàng)建主頁面:
    • src/index.html
  • 運行指令
    • 開發(fā)配置指令:webpack src/js/app.js -o dist/js/app.js --mode=development
      • 功能: webpack能夠編譯打包js和json文件,并且能將es6的模塊化語法轉換成瀏覽器能識別的語法
    • 生產配置指令:webpack src/js/app.js -o dist/js/app.js --mode=production
      • 功能: 在開發(fā)配置功能上加上一個壓縮代碼
  • 結論:
    • webpack能夠編譯打包js和json文件
    • 能將es6的模塊化語法轉換成瀏覽器能識別的語法
    • 能壓縮代碼
  • 缺點:
    • 不能編譯打包css、img等文件
    • 不能將js的es6基本語法轉化為es5以下語法
  • 改善:使用webpack配置文件解決,自定義功能

4、使用webpack配置文件

  • 目的:在項目根目錄定義配置文件,通過自定義配置文件,還原以上功能

  • 文件名稱:webpack.config.js

  • 文件內容:

    const { resolve } = require('path'); //node內置核心模塊,用來設置路徑。
    module.exports = {
      entry: './src/js/app.js',   // 入口文件配置(簡寫)
      /*完整寫法: 
      entry:{
        main:'./src/js/app.js'
      }
      */
      output: {                     // 輸出配置
        filename: './js/built.js',      // 輸出文件名
        path: resolve(__dirname, 'build')   //輸出文件路徑配置
      },
      mode: 'development'   //開發(fā)環(huán)境(二選一)
      mode: 'production'   //生產環(huán)境(二選一)
    };
    
  • 運行指令: webpack

5、打包less資源

  • 概述:less文件webpack不能解析,需要借助loader編譯解析

  • 創(chuàng)建less文件

    • src/less/test1.less
    • src/less/test2.less
  • 入口app.js文件

    • 引入less資源
  • 安裝loader

    • npm install css-loader style-loader less-loader less --save-dev
  • 配置loader

    {
      test: /\.less$/, // 檢查文件是否以.less結尾(檢查是否是less文件)
      use: [  // 數(shù)組中l(wèi)oader執(zhí)行是從下到上,從右到左順序執(zhí)行
        'style-loader', // 創(chuàng)建style標簽,添加上js中的css代碼
        'css-loader', // 將css以commonjs方式整合到js文件中
        'less-loader'  // 將less文件解析成css文件
      ]
    },
    
  • 運行指令:webpack

6、js語法檢查

  • 概述:對js基本語法錯誤/隱患,進行提前檢查

  • 安裝loader

    • npm install eslint-loader eslint --save-dev
  • 備注1:在:eslint.org網站 -> userGuide -> Configuring ESLint 查看如何配置

  • 備注2:在:eslint.org網站 -> userGuide -> Rules 查看所有規(guī)則

  • 配置loader

    module: {
      rules: [
        {
          test: /\.js$/,  //只檢測js文件
          exclude: /node_modules/,  //排除node_modules文件夾
          enforce: "pre",  //提前加載使用
          use: { //使用eslint-loader解析
            loader: "eslint-loader" 
          }
        }        
      ]
    }
    
  • 修改package.json(需要刪除注釋才能生效)

    "eslintConfig": {
      "parserOptions": {
        "ecmaVersion": 6,         // 支持es6
        "sourceType": "module"    // 使用es6模塊化
      },
      "env": { // 設置環(huán)境
        "browser": true,   // 支持瀏覽器環(huán)境: 能夠使用window上的全局變量
        "node": true       // 支持服務器環(huán)境:  能夠使用node上global的全局變量
      },
      "globals": {    // 聲明使用的全局變量, 這樣即使沒有定義也不會報錯了
        "$": "readonly"   // $ 只讀變量
      },
      "rules": {  // eslint檢查的規(guī)則  0 忽略 1 警告 2 錯誤
        "no-console": 0,  // 不檢查console
        "eqeqeq": 2,  // 用==而不用===就報錯
        "no-alert": 2 // 不能使用alert
      },
      "extends": "eslint:recommended" // 使用eslint推薦的默認規(guī)則 https://cn.eslint.org/docs/rules/
    },
    
  • 運行指令:webpack

7、js語法轉換

  • 概述:將瀏覽器不能識別的新語法轉換成原來識別的舊語法,做瀏覽器兼容性處理

  • 安裝loader

    • npm install babel-loader @babel/core @babel/preset-env --save-dev
  • 配置loader

    module: {
      rules: [
        {
          test: /\.js$/,
          exclude: /node_modules/,
          use: {
            loader: "babel-loader",
            options: {
              presets: ['@babel/preset-env']
            }
          }
        }
      ]
    }
    
  • 運行指令:webpack

8、 js兼容性處理

第一種方法:使用經典的polyfill

  • 安裝包

    • npm install @babel/polyfill
  • 使用

    - app.js
    
      import '@babel/polyfill'; // 包含ES6的高級語法的轉換
    
  • 優(yōu)點:解決babel只能轉換部分低級語法的問題(如:let/const/解構賦值...),引入polyfill可以轉換高級語法(如:Promise...)

  • 缺點:將所有高級語法都進行了轉換,但實際上可能只使用一部分(無論開發(fā)使用了幾個新語法,全部轉換成低級語法,不推薦使用)

  • 解決:需要按需加載(使用了什么高級語法,就轉換什么,而其他的不轉換)

第二種方法:借助按需引入core-js按需引入

  • 安裝包

    • npm install core-js
  • 配置loader

    {
      test: /\.js$/,
      exclude: /(node_modules)/,
      use: {
        loader: 'babel-loader',
        options: {
          presets: [
            [
              '@babel/preset-env',
              {
                useBuiltIns: 'usage',  // 按需引入需要使用polyfill
                corejs: { version: 3 }, // 解決warn
                targets: { // 指定兼容性處理哪些瀏覽器
                  "chrome": "58",
                  "ie": "9",
                }
              }
            ]
          ],
          cacheDirectory: true, // 開啟babel緩存
        }
      }
    },
    

9、打包樣式文件中的圖片資源

  • 概述:圖片文件webpack不能解析,需要借助loader編譯解析

  • 添加2張圖片:

    • 小圖, 小于8kb: src/images/vue.png
    • 大圖, 大于8kb: src/images/react.jpg
  • 在less文件中通過背景圖的方式引入圖片

  • 安裝loader

    • npm install file-loader url-loader --save-dev
    • 補充:url-loader是對象file-loader的上層封裝,使用時需配合file-loader使用。
  • 配置loader

    {
      test: /\.(png|jpg|gif)$/,
      use: {
        loader: 'url-loader',
        options: {
          limit: 8192, // 8kb --> 8kb以下的圖片會base64處理
          outputPath: 'images', // 決定文件本地輸出路徑
          publicPath: '../build/images',  // 決定圖片的url路徑
          name: '[hash:8].[ext]' // 修改文件名稱 [hash:8] hash值取8位  [ext] 文件擴展名
        }
      }
    },
    
  • 運行指令:webpack

10、打包html文件

  • 概述:html文件webpack不能解析,需要借助插件編譯解析

  • 添加html文件

    • src/index.html
    • 注意不要在html中引入任何css和js文件
  • 安裝插件Plugins

    • npm install html-webpack-plugin --save-dev
  • 在webpack.config.js中引入插件(插件都需要手動引入,而loader會自動加載)

    • const HtmlWebpackPlugin = require('html-webpack-plugin')
  • 配置插件Plugins

    plugins: [
      new HtmlWebpackPlugin({
        template: './src/index.html', // 以當前文件為模板創(chuàng)建新的HtML(1. 結構和原來一樣 2. 會自動引入打包的資源)
      }),
    ]
    
  • 運行指令:webpack

11、打包html中圖片資源

  • 概述:html中的圖片url-loader沒法處理,它只能處理js中引入的圖片 / 樣式中圖片,不能處理html中img標簽,需要引入其他html-loader處理。

  • 添加圖片

    • 在src/index.html添加兩個img標簽
  • 安裝loader

    • npm install html-loader --save-dev
  • 配置loader

    {
      test: /\.(html)$/,
      use: {
        loader: 'html-loader'
      }
    }
    
  • 運行指令:webpack

12、打包其他資源

  • 概述:其他資源webpack不能解析,需要借助loader編譯解析

  • 添加字體文件

    • src/media/iconfont.eot
    • src/media/iconfont.svg
    • src/media/iconfont.ttf
    • src/media/iconfont.woff
    • src/media/iconfont.woff2
  • 修改樣式

    @font-face {
      font-family: 'iconfont';
      src: url('../media/iconfont.eot');
      src: url('../media/iconfont.eot?#iefix') format('embedded-opentype'),
      url('../media/iconfont.woff2') format('woff2'),
      url('../media/iconfont.woff') format('woff'),
      url('../media/iconfont.ttf') format('truetype'),
      url('../media/iconfont.svg#iconfont') format('svg');
    }
    
    .iconfont {
      font-family: "iconfont" !important;
      font-size: 16px;
      font-style: normal;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
    }
    
  • 修改html,添加字體

  • 配置loader

    {
      test: /\.(eot|svg|woff|woff2|ttf|mp3|mp4|avi)$/,  // 處理其他資源
      loader: 'file-loader',
      options: {
        outputPath: 'media',
        name: '[hash:8].[ext]'
      }
    }
    
  • 運行指令:webpack

13、自動編譯打包運行

  • 安裝loader

    • npm install webpack-dev-server --save-dev
  • 詳細配置見官網:指南 -> 開發(fā)環(huán)境 -> 使用webpack-dev-server

  • 修改webpack配置對象(注意不是loader中)

    devServer: {
      open: true, // 自動打開瀏覽器
      compress: true, // 啟動gzip壓縮
      port: 3000, // 端口號
    }
    
  • 修改url-loader部分配置

    • 因為構建工具以build為根目錄,不用再找build了
    • publicPath: '../build/images/' --> publicPath: 'images/'
  • 修改package.json中scripts指令

    • "start": "webpack-dev-server",
  • 運行指令:npm run start

    • 注意webpack-dev-server指令才能啟動devServer配置,然后配置到package.json中才行

14、熱模替換功能

  • 概述:熱模塊替換(HMR)是webpack提供的最有用的功能之一。它允許在運行時更新所有類型的模塊,而無需完全刷新(只更新變化的模塊,不變的模塊不更新)。

  • 詳細配置見官網:指南 -> 模塊熱替換

  • 修改devServer配置

      devServer: {
        contentBase: resolve(__dirname, 'build'), // 運行項目的目錄
      open: true, // 自動打開瀏覽器
      compress: true, // 啟動gzip壓縮
      port: 3000, // 端口號
      hot: true // 開啟熱模替換功能 HMR
      }
    
  • 問題:html文件無法自動更新了,需要增加一個入口

      entry: ['./src/js/app.js','./src/index.html']
    

15、devtool

  • 概述: 一種將壓縮/編譯文件中的代碼映射回源文件中的原始位置的技術,讓我們調試代碼不在困難
  • 詳細配置見官網:配置 -> devtool
  • 介紹
    • cheap 只保留行, 編譯速度快
    • eval webpack生成的代碼(每個模塊彼此分開,并使用模塊名稱進行注釋), 編譯速度快
    • inline 以base64方式將source-map嵌入到代碼中,缺點造成編譯后代碼體積很大
  • 推薦使用:
    • 開發(fā)環(huán)境: cheap-module-eval-source-map
    • 生產環(huán)境: cheap-module-source-map

以上就是webpack開發(fā)環(huán)境的配置,可以在內存中自動打包所有類型文件并有自動編譯運行、熱更新等功能。

16、準備生產環(huán)境

  • 創(chuàng)建文件夾config,將webpack.config.js復制兩份

    • ./config/webpack.dev.js
    • ./config/webpack.prod.js
  • 修改webpack.prod.js配置,刪除webpack-dev-server配置

    // / 代表根路徑(等價于這個:http://localhost:5000/),以后項目上線所有路徑都以當前網址為根路徑出發(fā)
    module.exports = {
      output: {
        path: resolve(__dirname, '../build'), // 文件輸出目錄
        filename: './js/built.js', // 文件輸出名稱
        publicPath: '/'  // 所有輸出資源在引入時的公共路徑,若loader中也指定了publicPath,會以loader的為準。
      },
    module: {
      rules: [
      {
            test: /\.(png|jpg|gif)$/,
            use: {
              loader: 'url-loader',
              options: {
                limit: 8192, 
                outputPath: 'images', 
                publicPath: '/images',  // 重寫publicPath,需要在路徑前面加上 /
                name: '[hash:8].[ext]' 
              }
            }
          },  
      ]
    },
      mode: 'production',  //修改為生產環(huán)境
    devtool: 'cheap-module-source-map' // 修改為生產環(huán)境的錯誤提示
    // 刪除devServer
    }
    
  • 修改package.json的指令

    • "start": "webpack-dev-server --config ./config/webpack.dev.js"
    • "dev": "webpack-dev-server --config ./config/webpack.dev.js"
    • "build": "webpack --config ./config/webpack.prod.js"
  • 開發(fā)環(huán)境指令

    • npm start
    • npm run dev
  • 生產環(huán)境指令

    • npm run build
    • 注意: 生產環(huán)境代碼需要部署到服務器上才能運行 (serve這個庫能幫助我們快速搭建一個靜態(tài)資源服務器)
      • npm i serve -g
      • serve -s build -p 5000

17、清除打包文件目錄

  • 概述:每次打包生成了文件,都需要手動刪除,引入插件幫助我們自動刪除上一次的文件
  • 安裝插件
    • npm install clean-webpack-plugin --save-dev
  • 引入插件
    • const { CleanWebpackPlugin } = require('clean-webpack-plugin'); // 注意要解構賦值!??!
  • 配置插件
    • new CleanWebpackPlugin() // 自動清除output.path目錄下的文件
  • 運行指令:npm run build

18、提取css成單獨文件

  • 安裝插件

    • npm install mini-css-extract-plugin --save-dev
  • 引入插件

    • const MiniCssExtractPlugin = require("mini-css-extract-plugin");
  • 配置loader

    {
      test: /\.less$/,
      use: [
        MiniCssExtractPlugin.loader,
        'css-loader',
        'less-loader',
      ]
    }
    
  • 配置插件

    new MiniCssExtractPlugin({
      filename: "css/[name].css",
    })
    
  • 運行指令

    • npm run build
    • serve -s build

19、添加css兼容

  • 安裝loader

    • npm install postcss-loader postcss-flexbugs-fixes postcss-preset-env postcss-normalize autoprefixer --save-dev
  • 配置loader

    {
      test: /\.less$/,
      use: [
        MiniCssExtractPlugin.loader,
        'css-loader',
        {
          loader: 'postcss-loader',
          options: {
            ident: 'postcss',
            plugins: () => [
              require('postcss-flexbugs-fixes'),
              require('postcss-preset-env')({
                autoprefixer: {
                  flexbox: 'no-2009',
                },
                stage: 3,
              }),
              require('postcss-normalize')(),
            ],
            sourceMap: true,
          },
        },
        'less-loader',
      ]
    }
    
  • 添加配置文件: .browserslistrc

    last 1 version
    > 1%
    IE 10 # sorry
    
  • 運行指令:

    • npm run build
    • serve -s build

20、壓縮css

  • 安裝插件

    • npm install optimize-css-assets-webpack-plugin --save-dev
  • 引入插件

    • const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
  • 配置插件

    new OptimizeCssAssetsPlugin({
      cssProcessorPluginOptions: {
        preset: ['default', { discardComments: { removeAll: true } }],
      },
      cssProcessorOptions: { // 解決沒有source map問題
        map: {
          inline: false,
          annotation: true,
        }
      }
    })
    
  • 運行指令:

    • npm run build
    • serve -s build

21、壓縮html

  • 修改插件配置

    new HtmlWebpackPlugin({
      template: './src/index.html',
      minify: {
        removeComments: true,
        collapseWhitespace: true,
        removeRedundantAttributes: true,
        useShortDoctype: true,
        removeEmptyAttributes: true,
        removeStyleLinkTypeAttributes: true,
        keepClosingSlash: true,
        minifyJS: true,
        minifyCSS: true,
        minifyURLs: true,
      }
    })
    
  • 運行指令:

    • npm run build
    • serve -s dist

以上就是webpack生產環(huán)境的配置,可以生成打包后的文件。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內容