webpack 實踐 - 基礎篇

[toc]css

這篇專欄文章介紹了 webpack 的概念與基礎用法,而且介紹了經常使用的實際應用場景,相信看完後就能夠搭建一套本身的 web 構建程序。html

1 概念

本質上,webpack 是一個現代 JavaScript 應用程序的靜態模塊打包器(module bundler)。當 webpack 處理應用程序時,它會遞歸地構建一個依賴關係圖(dependency graph),其中包含應用程序須要的每一個模塊,而後將全部這些模塊打包成一個或多個 bundle。node

2 基礎配置屬性介紹

2.1 entry

打包的入口文件,打包時會根據入口文件找到項目的依賴,造成一棵依賴樹。react

2.1.1 單入口:

一個應用只有一個入口,適合單頁應用。webpack

module.exports = {
  entry: './src/index.js'
}
複製代碼

2.1.2 多入口:

適合多頁面應用,entry 是一個對象es6

module.exports = {
  entry: {
      app: './src/index.js',
      home: './src/home.js',
  }
}
複製代碼

2.2 output

設置打包的出口web

參數:express

  • path: 打包後的文件目錄。
  • filename:打包後的文件名字。能夠用 [name] 的形式對文件名佔位
var path = require('path');
module.exports = {
  entry: {
    index: './src/index.js',
    home: './src/home.js'
  },
  output: {
    path: path.join(__dirname, 'dist'),
    filename: '[name].js',
  }
}
複製代碼

2.3 loaders

webpack 自己只支持 js 和 json 兩種文件類型,經過 loaders 去支持其餘文件類型而且能夠添加到依賴樹中,好比 html、jsx、css、圖片等。loaders 自己是一個函數,將文件輸入並轉換出想要的文件。npm

2.3.1 用法

參數:json

  • test:匹配規則
  • loader:loader 名字
  • exclude:排除規則
  • query | options: loader 參數
modules.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,
        loader: 'style-loader!css-loader'
      },
      { test: /\.tsx?$/,
        loader: 'ts-loader'
      },
      {
        test: /\.js?$/,
        exclude: /(node_modules|packages)/,  // 排除的目錄
        loader: 'babel-loader',
        query: {presets: ['es2015', 'react']}} // 配置參數
    ]
  },
};
複製代碼

2.3.2 經常使用的 loader

  • babel-loader:轉換es六、es7等新js語法
  • css-loader: 支出 css 的加載解析,在頁面中能夠經過 import 的方式將 css 引入頁面
  • scss-loader:將 less 文件轉換成 css
  • ts-loader: 將 ts 轉換爲 js
  • file-loader:進行圖片、字體等文件的解析
  • url-loader: 內置了 file-loader,能夠設置 ‘limit’,當文件體積小於 limit 的時候將文件轉成 DataURL,當大於 limit 的時候調用 file-loader 處理。
  • raw-loader:將文件以字符串的形式導入
  • thread-loader:使用多進程打包,用於打包速度優化處理耗時 loader
  • cache-loader: 將其後面 loader 打包的結果緩存到磁盤

2.4 plugins

插件。打包過程當中文件處理的一部分,添加打包過程當中的各類功能。

2.4.1 用法

modules.exports = {
  entry: {
      index: './src/index.js'
  },
  plugins: [
    new HtmlWebpackPlugin({template: './index.html'})
  ],
};
複製代碼

2.4.2 經常使用的 plugins

  • Webpack-dev-server: 是一個express服務器,提供項目運行服務(自帶熱更新)
  • CommonsChunkPlugin:將公用的js提取出來做爲獨立的的模塊
  • CleanWebpackPlugin:清理構建目錄
  • ExtractTextWebpackPlugin:將 css 從 bundle 中提取出來做爲獨立的文件
  • HtmlWebpackPlugin: 建立 html 文件並將打包後的文件插入進去
  • speed-measure-webpack-plugin 構件時會列出各個 loader 和 plugin 消耗時間信息,可用於分析優化策略
  • Happypack:使用多進程打包,用於打包速度優化

2.5 model

指定當前環境

值:

  • production:線上環境。自動開啓FlagDependencyUsagePlugin、FlagIncludeChunksPlugin、ModuleCocatenationPlugin、NoemitOnErrorsPlugin、OccurrenceOrderPlugin、SideEffectsFlagPlugin、TerserPlugin。自動對代碼進行壓縮、識別打包時反作用的參數等。
  • development:開發環境。自動開啓 NamedChunksPlugin、NamedModulesPlugin。在 HMR 階段在控制檯打印更新的目錄。
  • none:不開啓任何優化選項。
modules.exports = {
  mode: 'production',
};
複製代碼

3 實際應用

3.1 以 npm 命令的形式運行 webpack

webpack 的運行命令通常比較長,若是參數比較多的話會更長,能夠把 webpack 以 npm 命令的方式執行

  1. 將命令配置在 package.json
{
    "scripts": {
        "build": "webpack --config=./webpack.config.js",
    }
}
複製代碼
  1. 使用的時候直接運行 npm run build

3.2 利用 babel 解析 es6 和 '.jsx'

須要用到 babel-loader, 上面說過 loader 是用來處理輸入文件而後轉義成想要的輸出文件的,這裏以 轉義 es6 語法 與 react .jsx 語法爲例。轉義其餘類型的文件如 .scss 方式雷同,只不過 loader 與配置參數不同

  1. 下載 babel 相關依賴
npm i -D @babel/core @babel/preset-env babel-loader
複製代碼
  1. 建立 babel的配置文件 .babelrc(更多 babel 相關配置請看 babel 文檔)
{
    "presets": [
        "@babel/preset-env",
        "@babel/preset-react"
    ]
}
複製代碼
  1. 配置 webpack.config.js
module.exports = {
    module: {
        rules: [
            {
                test: /\.js(x?)$/,
                exclude: /(node_modules)/,
                use: {
                    loader: 'babel-loader',
                }
            },
        ],
    },
};
複製代碼

注: babel-loader 還支持不使用 .babelrc ,直接在 babel-loader 的參數中配置 babel, 下面的方式與上面的效果同樣

module.exports = {
    module: {
        rules: [
            {
                test: /\.js(x?)$/,
                exclude: /(node_modules)/,
                use: {
                    loader: 'babel-loader',
                    query: {
                        presets: ['env', 'react'],
                    }
                }
            },
        ],
    },
};
複製代碼

3.3 將 js 自動以 <script/> 的形式插入 html

這裏介紹的是 Plugin 的實際應用(plugin 的做用上面介紹過了),本示例中會用到 HtmlWebpackPlugin

  1. 下載 HtmlWebpackPlugin
npm i -D html-webpack-plugin
複製代碼
  1. webpack.config.js 中引入並使用

每一個模板頁必須單獨配置 HtmlWebpackPlugin,若是有多個頁面就得使用多個 HtmlWebpackPlugin, 下面示例配置了 'index' 與 'home' 兩個文件的模板。

const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    entry: {
        index: './src/index/index.jsx',
        home: './src/home/home.jsx'
    },
    output: {
        path: path.join(__dirname, 'dist'),
        filename: '[name]/[name].[chunkhash:8].js'
    },
    plugins: [
        new HtmlWebpackPlugin({
            chunks:['index'],  // 說明要加載的模塊(不指定的話,index.js 與 home.js 都會引進來)
            filename: 'index/index.html', // 輸出位置與名字
            template: 'src/index/index.html'  // 模板位置
        }),
        new HtmlWebpackPlugin({
            chunks:['home'],
            filename: 'home/home.html',
            template: 'src/home/home.html'
        }),
    ],
}
複製代碼

: 更多配置,請看 HtmlWebpackPlugin 文檔

3.4 將 css 與 js 分離,並插入 html

默認 webpack 在打包的時候會將 css 打包進引用的 bundle.js 中, 咱們能夠用 ExtractTextWebpackPlugin 將 css 分離出來,以實現 js、html 與 css 的分離,與通用 css 複用的目的。下面的例子順便介紹了 sass 的轉譯

  1. 下載 css 相關 loader 與 ExtractTextWebpackPlugin
npm i -D css-loader sass-loader extract-text-webpack-plugin
複製代碼
  1. webpack.config.js 配置
const ExtractTextWebpackPlugin = require('extract-text-webpack-plugin');

module.exports = {
    module: {
        rules: [
             {
                test: /\.scss$/,
                use: ExtractTextWebpackPlugin.extract({
                    use: [
                        {loader: 'css-loader'},
                        {loader: 'sass-loader'},
                    ],
                }),
            },
        ],
    },
    plugins: [
        new ExtractTextWebpackPlugin({
            allChunks: true,
            filename: '[name]/[name].[hash:8].css',
        }),
    ],
}
複製代碼

: 上面的例子對 .scss 文件進行了轉譯,而且在在輸出的 css 文件後加了 hash 值(每次修改 css 都會變,避免緩存)。編譯後的 css 文件會以 <link/> 的形式插入 html

3.5 本地 server 開發 && 熱更新

使用 webpack-dev-server 能夠在本地啓動 node server 並啓一個端口,同時其默認開啓熱更新以便在開發過程當中實時觀看代碼修改的效果

  1. 下載 webpack-dev-server
npm i -D webpack-dev-server
複製代碼
  1. 配置 webpack.config.js
module.exports = {
    devServer: {
        index: 'index/index.html',  // 入口文件
        contentBase: [path.join(__dirname, 'dist')],  // 打包後的資源目錄
        compress: true,
        port: 9000 // 端口
    }
}
複製代碼
  1. 在 package.json 配置 npm 命令, 並啓動
{
  "scripts": {
      "start": "webpack-dev-server"
  },
}
複製代碼

注: webpack-dev-server 還支持函數式的使用方式,以在運行過程當中提供更靈活的配置。詳情見文檔

5 性能優化

待續。。。

6 編寫本身的 loader

待續。。。

接下來會將會深刻介紹 webpack 的原理、我在實際工做中遇到的問題與性能優化、並親手寫一個屬於本身的 loader。這些文章應該會單獨啓一篇,到時候會將連接貼在這。喜歡的小夥伴能夠比心並持續關注哦

相關文章
相關標籤/搜索