1. 程式人生 > >webpack 4.x 初級學習記錄

webpack 4.x 初級學習記錄

但是 模式 基本概念 寫入 dex www 命令 output 參數

目錄

  • webpack 4.x 安裝
    • webpack 4.x 基本打包編譯
  • webpack 配置
    • 概念
  • webpack-dev-server
    • 安裝
    • 基本概念
    • 配置webpack.config.js
    • 配置package.json
  • webpack loader處理
    • 安裝
    • 配置
    • HTML的img標記處理
    • CSS 打包分離
  • webpack 插件
    • 剖析
    • 用法
    • 配置
  • webpack babel
    • 安裝
    • 配置
  • webpack 引入第三方庫
    • 安裝
    • 使用

首先聲明下,本人不擅長文字表達,文采不行,所以文章中文字較少,請看代碼,初級學習,不足之處請多多指教

GitHub鏈接

webpack 4.x 安裝

  1. 首先需要在全局中安裝
npm install webpack -g
npm install webpack-cli -g  // 與webpack 3.x 的區別
  1. 接下來打開新的文件夾,創建package.json
npm init

初始化 package.json 文件。

  1. 局部安裝
npm install webpack --save
npm install webpack-cli --save

webpack 4.x 基本打包編譯

  1. webpack 3.x 編譯
webpack a.js b.js
# {extry file}出填寫入口文件的路徑,本文中就是上述main.js的路徑,
# {destination for bundled file}處填寫打包文件的存放路徑
# 填寫路徑的時候不用添加{}
webpack {entry file} {destination for bundled file}

以上就是4版本之前的使用方式,但是這種方式在4版本中就不能使用了,4版本有自己的新的方式

  1. webpack 4.x 默認打包編譯

為什麽上面要寫默認打包編譯,是因為webpack可以自定義打包編譯配置,我們首先說下默認的打包編譯。

entry: "/src/index.js"  // 默認入口文件
output: "/dist/main.js"  // 默認輸入文件

上面路徑及文件中,srcindex.js 需要我們手動去創建,在 index.js 中寫好js代碼即可,其余的 distmain.js 都是由系統自動生成的,並且當你再一次編譯時,會自動的在 dist 中覆蓋同名文件。

而webpack 4.x 的編譯命令也發生變化了,如下所示,分為開發環境和生產環境的命令

webpack --mode development
webpack --mode production

使用命令後,會自動生成文件。

配置 package.json 文件

"scripts": {
    "dev": "webpack --mode development",
    "build": "webpack --mode production"
}

可以使用 npm ruin devnpm run build 進行執行命令

webpack 配置

概念

本質上,webpack 是一個現代 JavaScript 應用程序的靜態模塊打包器(static module bundler)。在 webpack 處理應用程序時,它會在內部創建一個依賴圖(dependency graph),用於映射到項目需要的每個模塊,然後將所有這些依賴生成到一個或多個bundle。

從 webpack 4.0.0 版本開始,可以不用通過引入一個配置文件打包項目。然而,webpack 仍然還是 高度可配置的,並且能夠很好的滿足需求。

webpack 的核心概念:

  1. 入口(entry)
  2. 輸出(output)
  3. loader
  4. 插件(plugins)

我們需要在根目錄下創建一個 webpack.config.js 的文件,使用 Commonjs 規範來進行書寫。

入口(entry)

入口起點(entry point)指示 webpack 應該使用哪個模塊,來作為構建其內部依賴圖的開始。進入入口起點後,webpack 會找出有哪些模塊和庫是入口起點(直接和間接)依賴的。

可以通過在 webpack 配置中配置 entry 屬性,來指定一個入口起點(或多個入口起點)。默認值為 ./src

module.exports = {
  entry: "./src/index.js",
};

entry 屬性的單個入口語法,是下面的簡寫:

module.exports = {
  entry: {
    main: "./src/index.js",
  }
};

當你向 entry 傳入一個數組時會發生什麽?向 entry 屬性傳入「文件路徑(file path)數組」將創建“多個主入口(multi-main entry)”。在你想要多個依賴文件一起註入,並且將它們的依賴導向(graph)到一個“chunk”時,傳入數組的方式就很有用。

多個入口文件處理

module.exports = {
  entry: {
    main: "./src/index.js",
    app: ‘./src/app.js‘
  }
};

根據經驗:每個 HTML 文檔只使用一個入口起點。 當然也可以使用多個,但是推薦一個使用一個

了解更多

輸出(output)

output 屬性告訴 webpack 在哪裏輸出它所創建的 bundles,以及如何命名這些文件,默認值為 ./dist。基本上,整個應用程序結構,都會被編譯到你指定的輸出路徑的文件夾中。你可以通過在配置中指定一個 output 字段,來配置這些處理過程:

const path = require(‘path‘);

module.exports = {
  entry: "./src/index.js"
  output: {
    path: path.resolve(__dirname, ‘dist‘),
    filename: ‘bundle.js‘
  }
};

當然上面的位置文件名都是可以改變的,可以自定義配置。

在上面的示例中,我們通過 output.filenameoutput.path 屬性,來告訴 webpack bundle 的名稱,以及我們想要 bundle 生成(emit)到哪裏

了解更多

loader


loader 讓 webpack 能夠去處理那些非 JavaScript 文件(webpack 自身只理解 JavaScript)。loader 可以將所有類型的文件轉換為 webpack 能夠處理的有效模塊,然後你就可以利用 webpack 的打包能力,對它們進行處理。

本質上,webpack loader 將所有類型的文件,轉換為應用程序的依賴圖(和最終的 bundle)可以直接引用的模塊。

註意,loader 能夠 import 導入任何類型的模塊(例如 .css 文件),這是 webpack 特有的功能,其他打包程序或任務執行器的可能並不支持。我們認為這種語言擴展是有很必要的,因為這可以使開發人員創建出更準確的依賴關系圖。

在更高層面,在 webpack 的配置中 loader 有兩個目標:

  1. test 屬性,用於標識出應該被對應的 loader 進行轉換的某個或某些文件。
  2. use 屬性,表示進行轉換時,應該使用哪個 loader。
const path = require(‘path‘);

const config = {
  entry: "./src/index.js"
  output: {
    path: path.resolve(__dirname, ‘dist‘),
    filename: ‘bundle.js‘
  },
  module: {
    rules: [
      { test: /\.txt$/, use: ‘raw-loader‘ }
    ]
  }
};

module.exports = config;

以上配置中,對一個單獨的 module 對象定義了 rules 屬性,裏面包含兩個必須屬性:test 和 use。這告訴 webpack 編譯器(compiler) 如下信息:

“嘿,webpack 編譯器,當你碰到「在 require()/import 語句中被解析為 ‘.txt‘ 的路徑」時,在你對它打包之前,先使用 raw-loader 轉換一下。”

了解更多

插件(plugins)

loader 被用於轉換某些類型的模塊,而插件則可以用於執行範圍更廣的任務。插件的範圍包括,從打包優化和壓縮,一直到重新定義環境中的變量。插件接口功能極其強大,可以用來處理各種各樣的任務。

想要使用一個插件,你只需要 require() 它,然後把它添加到 plugins 數組中。多數插件可以通過選項(option)自定義。你也可以在一個配置文件中因為不同目的而多次使用同一個插件,這時需要通過使用 new 操作符來創建它的一個實例。

const HtmlWebpackPlugin = require(‘html-webpack-plugin‘); // 通過 npm 安裝
const webpack = require(‘webpack‘); // 用於訪問內置插件

const config = {
  module: {
    rules: [
      { test: /\.txt$/, use: ‘raw-loader‘ }
    ]
  },
  plugins: [
    new webpack.optimize.UglifyJsPlugin(),
    new HtmlWebpackPlugin({template: ‘./src/index.html‘})
  ]
};

module.exports = config;

webpack 提供許多開箱可用的插件!查閱插件列表獲取更多信息。

在 webpack 配置中使用插件是簡單直接的,然而也有很多值得我們進一步探討的用例。

了解更多

webpack-dev-server

本地服務器

安裝

npm install webpack-dev-server -S

基本概念

可以構建一個本地服務器進行啟動測試

配置webpack.config.js

webpack.config.js

devServer: {
    contentBase: path.join(__dirname, "/dist"),  //啟動路徑
    port: 9001,  // 端口號
    hot: true,  // 熱更新
    inline:true  // 內聯模式
}

當然在使用上面 hot 熱更新時需要開啟一個插件 HotModuleReplacementPlugin 此插件屬於內置插件,可以直接使用 new webpack.HotModuleReplacementPlugin() 來進行啟用

以上使 webpack-dev-server 的基本參數用法,具體的可以查看此處

配置package.json

"scripts": {
    "start": "webpack-dev-server --open"
}

使用 npm start 開啟啟動命令

webpack loader處理

loader : 加載程序

loader 用於對模塊的源代碼進行轉換。loader 可以使你在 import 或"加載"模塊時預處理文件。因此,loader 類似於其他構建工具中“任務(task)”,並提供了處理前端構建步驟的強大方法。loader 可以將文件從不同的語言(如 TypeScript)轉換為 JavaScript,或將內聯圖像轉換為 data URL。loader 甚至允許你直接在 JavaScript 模塊中 import CSS文件!

安裝

cnpm install css-loader style-loader -S

配置

當新建文件 *.css 文件時進行css文件處理

webpack.config.js

module:{
    rules:[
        {
            test:/\.css$/,
            use:[‘style-loader‘,‘css-loader‘]
        }
    ]
}

在其中需要註意的就是 style-loadercss-loader 之前。

當 css 有 background-image: url(‘./1.jpg‘) 有圖片插入進來時,需要使用 file-loader 來進行處理

module:{
    rules:[
        {
            test:/\.css$/,
            use:[‘style-loader‘,‘css-loader‘]
        },
        {
            test:/\.(jpg|png|jpeg)$/,
            use:[‘file-loader‘]
        }
    ]
}

設置圖片保存地方及是否使用base64進行處理

{
    test:/\.(jpg|png|jpeg)$/,
    use:‘file-loader?limit=1024&name=./images/[hash:8].[name].[ext]‘
}

HTML的img標記處理

安裝

cnpm install html-withimg-loader -S

配置

{
    test:/\.html$/,
    use:["html-withimg-loader"]
}

CSS 打包分離

安裝

cnpm install extract-text-webpack-plugin@next -S

配置

const ExtractTextPlugin=require(‘extract-text-webpack-plugin‘);

//插件
new ExtractTextPlugin(‘./css/[name].css‘)

// rules
{
    test:/\.css$/,
    use:ExtractTextPlugin.extract({
        fallback:"style-loader",
        use:[{
            loader:"css-loader",
            options:{
                // 壓縮
                minimize:true
            }
        }],
        // 添加公共路徑
        publicPath:"../"
    })
}

webpack 插件

插件是 webpack 的支柱功能。webpack 自身也是構建於,你在 webpack 配置中用到的相同的插件系統之上!

插件目的在於解決 loader 無法實現的其他事。

剖析

webpack 插件是一個具有 apply 屬性的 JavaScript 對象。apply 屬性會被 webpack compiler 調用,並且 compiler 對象可在整個編譯生命周期訪問。

ConsoleLogOnBuildWebpackPlugin.js

const pluginName = ‘ConsoleLogOnBuildWebpackPlugin‘;

class ConsoleLogOnBuildWebpackPlugin {
    apply(compiler) {
        compiler.hooks.run.tap(pluginName, compilation => {
            console.log("webpack 構建過程開始!");
        });
    }
}

compiler hook 的 tap 方法的第一個參數,應該是駝峰式命名的插件名稱。建議為此使用一個常量,以便它可以在所有 hook 中復用。

用法

由於插件可以攜帶參數/選項,你必須在 webpack 配置中,向 plugins 屬性傳入 new 實例。

根據你的 webpack 用法,這裏有多種方式使用插件。

配置

webpack.config.js

const HtmlWebpackPlugin = require(‘html-webpack-plugin‘); //通過 npm 安裝
const webpack = require(‘webpack‘); //訪問內置的插件
const path = require(‘path‘);

const config = {
  entry: ‘./path/to/my/entry/file.js‘,
  output: {
    filename: ‘my-first-webpack.bundle.js‘,
    path: path.resolve(__dirname, ‘dist‘)
  },
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        use: ‘babel-loader‘
      }
    ]
  },
  plugins: [
    new webpack.optimize.UglifyJsPlugin(),
    new HtmlWebpackPlugin({template: ‘./src/index.html‘})
  ]
};

module.exports = config;

當然上面的 HtmlWebpackPlugin 插件只使用了基本的功能,更多的參數可以去github上查看。

webpack babel

安裝

核心
babel-core

功能
babel-loader
babel-preset-env
babel-preset-react

babel-loader 7.x 版本安裝

cnpm install babel-core babel-loader@7 babel-preset-env babel-preset-react --save

安裝的 babel-loader 是7.x版本,8.x版本目前會出現報錯,具體如何解決還沒有了解清楚,所以安裝 babel-loader 時需要寫成這樣的 babel-loader@7

babel-loader 8.x 版本安裝

cnpm install -D babel-loader @babel/core @babel/preset-env @babel/preset-react -S

上面為 babel-loader 8.x 版本安裝,需要匹配下面的 8.x 配置

配置

babel-loader 7.x 版本配置

第一種 全在 webpack.config.js 中配置

rules:[
    {
        test:/\.(jsx|js)$/,
        use:{
            loader:‘babel-loader‘,
            options:{
                presets:[‘env‘,‘react‘]
            }
        },
        // 排除node_modules 文件
        exclude:/node_modules/
    }
]

第二種 新建 .babelrc 文件 (推薦使用第二種)

webpack.config.js

rules:[
    {
        test:/\.(jsx|js)$/,
        use:{
            loader:‘babel-loader‘
        },
        // 排除node_,modules 文件
        exclude:/node_modules/
    }
]

.baelrc

{
    "presets": [
        "env",
        "react"
    ]
}

babel-loader 8.x 版本配置

第一種 全在 webpack.config.js 中配置

rules:[
    {
        test:/\.(jsx|js)$/,
        use:{
            loader:‘babel-loader‘,
            options:{
                presets:[‘"@babel/preset-env‘,‘"@babel/preset-react‘]
            }
        },
        // 排除node_modules 文件
        exclude:/node_modules/
    }
]

第二種 新建 .babelrc 文件 (推薦使用第二種)

webpack.config.js

rules:[
    {
        test:/\.(jsx|js)$/,
        use:{
            loader:‘babel-loader‘
        },
        // 排除node_,modules 文件
        exclude:/node_modules/
    }
]

.baelrc

{
    "presets": [
        ""@babel/preset-env",
        ""@babel/preset-react"
    ]
}

webpack 引入第三方庫

安裝

cnpm install jquery -S

使用

在webpack 3.x 中需要大量配置,但是在webpack中則少了很多

const $ = require("jquery");

$("body").html("<p>我是由JQuery寫出來的</p>")

webpack 4.x 初級學習記錄