超詳細使用webpack4.x搭建標準前端項目

在開始教程前,先看看咱們經過本教程能學到什麼。

目錄

1 小試牛刀javascript

1.1 建立並初始化項目css

1.2 建立目錄及文件html

1.3 修改package.json前端

1.4 編寫項目代碼java

1.5 配置webpack.config.jsnode

1.6 測試打包jquery

2 搭建基礎架構webpack

2.1 實現每次編譯前自動清空dist目錄git

2.2 實現從html模板自動生成最終htmlgithub

2.3 構建項目

3 搭建開發環境的熱監測服務器

3.1 安裝webpack-dev-server

3.2 使用source-map追蹤源代碼錯誤

4 分離生產環境和開發環境的配置文件

5 集成公用JS庫(以jQuery爲例)

5.1 安裝並集成jQuery

5.2 全局應用jQuery

5.3 使用jQuery

5.4 單獨打包jQuery

6 兼容IE8處理方式

6.1 解決IE8「缺乏標識符」錯誤

6.2 解決ES6轉ES5

6.3 解決IE8「對象不支持bind屬性方法」錯誤

7 CSS及Stylus的使用

7.1 加載CSS和Stylus

7.2 分離樣式到css文件

7.3 優化分離css公用樣式

8 使用ejs將html模塊化

9 加載圖片資源

9.1 css加載圖片

9.2 html加載圖片

9.3 解決css和html中引用圖片路徑不一致的問題

10 加載iconfont

11 使用cnpm加速下載

1 小試牛刀

1.1 建立並初始化項目

找個喜歡的目錄,執行如下命令:

mkdir webpack-demo
cd webpack-demo
npm init -y
npm install webpack webpack-cli --save-dev
複製代碼

1.2 建立目錄及文件

※注:本文代碼區域每行開頭的 「+」表示新增,「-或者D」表示刪除,「M」表示修改,「...」表示省略。

dist爲最終編譯出來的生產環境代碼,src爲開發環境代碼。

/- webpack-demo
    |- package.json
+   |- /dist
+      |- index.html
+   |- /src
+      |- index.js
複製代碼

1.3 修改package.json

調整 package.json 文件,以便確保咱們安裝包是私有的(private),而且移除 main 入口。這能夠防止意外發布你的代碼。

同時加入script命令,讓執行npx webpack 等同於執行npm run build。

"name": "webpack-demo",
    "version": "1.0.0",
    "description": "",
+   "private": true,
-   "main": "index.js",
    "scripts": {
-      "test": "echo \"Error: no test specified\" && exit 1",
+      "build": "webpack --mode production",
+      "dev": "webpack --mode development"
     },
    ...
複製代碼

1.4 編寫項目代碼

編寫dist/index.html,注意引入bundle.js(打包時會自動生成bundle.js)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Webpack Demo</title>
    <script src="bundle.js"></script>
</head>
<body>
</body>
</html>

複製代碼

編寫src/index.js,隨便寫點。

document.write('hello world');
複製代碼

1.5 配置webpack.config.js

項目根目錄建立webpack.config.js,用來配置webpack。

|- package.json
    |- /dist
       |- index.html
    |- /src
       |- index.js
+   |- webpack.config.js 
複製代碼

編寫webpack.config.js:

const path = require('path');
module.exports = {
    // 入口js路徑
    entry: './src/index.js',
    // 編譯輸出的js及路徑
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist')
    }
};
複製代碼

1.6 測試打包

執行npm run build,生成的dist以下:

|-  /dist
    |- index.html
+   |- bundle.js   
複製代碼

瀏覽器運行index.html,顯示「hello world」。

以上是最原始的方式,須要在dist配置html,這樣並不科學。咱們須要實現的是在src裏開發,而後所有生成到dist中。請繼續後面的章節。

2 搭建基礎架構

2.1 實現每次編譯前自動清空dist目錄

安裝clean-webpack-plugin,設置代碼見2.3

npm install clean-webpack-plugin --save-dev
複製代碼

2.2 實現從html模板自動生成最終html

安裝html-webpack-plugin,設置代碼見2.3

npm install html-webpack-plugin --save-dev
複製代碼

2.3 構建項目

構建目錄以下

|- package.json
  |- webpack.config.js
  |- /dist
  |- /src
     |- /html
        |- index.html
        |- login.html
     |- /js
        |- index.js
        |- login.js 
複製代碼

從新編寫webpack.config.js

const path = require('path');
const {CleanWebpackPlugin} = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
    // 入口js路徑
    entry: {
        index: './src/js/index.js',
        login: './src/js/login.js'
    },
    plugins: [
        // 自動清空dist目錄
        new CleanWebpackPlugin(),
        // 設置html模板生成路徑
        new HtmlWebpackPlugin({
            filename: 'index.html',
            template: './src/html/index.html',
            chunks: ['index']
        }),
        new HtmlWebpackPlugin({
            filename: 'login.html',
            template: './src/html/login.html',
            chunks: ['login']
        }),
    ],
    // 編譯輸出配置
    output: {
        // js生成到dist/js,[name]表示保留原js文件名
        filename: 'js/[name].js',
        // 輸出路徑爲dist
        path: path.resolve(__dirname, 'dist')
    }
};
複製代碼

如今執行npm run build,生成dist以下:

|- /dist
    |- index.html
    |- login.html
    |- /js
       |- index.js
       |- login.js
複製代碼

查看html代碼,發現對應的js已經被引入了。

3 搭建開發環境的熱監測服務器

如今咱們搭建一個基於nodejs的服務器,讓代碼運行在開發環境,而且實如今修改代碼時不用刷新便可自動熱更新頁面。

3.1 安裝webpack-dev-server

自動監測代碼變化並實時刷新瀏覽器

npm install webpack-dev-server --save-dev
複製代碼

修改package.json:

"scripts": {
        "build": "webpack --mode production",
-       "dev": "webpack --mode development"
+       "serve": "webpack-dev-server --open --mode development"
    },
複製代碼

修改webpack.config.js:

module.exports = {
       entry: {...},
+      // 動態監測並實時更新頁面
+      devServer: {
+          contentBase: './dist',
+          // 默認8080,可不寫
+          port: 8080,
+          // 熱更新,無需刷新
+          hot: true
+      },
        plugins: [...],
    ...
    };

複製代碼

執行npm run serve,會在本地啓動一個nodejs的web服務,瀏覽器會自動打開http://localhost:8080/。

經過http://localhost:8080/login.html能夠訪問login頁面。

這時修改src下的js或者html文件,頁面會自動更新。

3.2 使用source-map追蹤源代碼錯誤

在編譯生成的dist目錄中,js代碼已被從新混淆,若是出現錯誤,沒法將錯誤正肯定位到原始代碼的對應位置,這樣不方便調試生成環境的代碼。若是須要精確調試生產環境代碼,可經過source-map實現。(若是不須要此功能,能夠跳過本節)

修改webpack.config.js:

inline-source-map: 將source map 轉換爲 DataUrl 後添加到頁面的js中,生成的js文件較大(不推薦)

source-map: 生成對應的map文件,js較小,可是須要服務器設置不容許訪問map文件(推薦)

module.exports = {
        ...
        devServer: {...},
+       // 方便追蹤源代碼錯誤
+       devtool: 'source-map',
        plugins: [...],
        ..
    };
複製代碼

4 分離生產環境和開發環境的配置文件

webpack.config.js包含了生產環境和開發環境的配置,分離後,有利於代碼的維護。

安裝webpack-merge插件

使用裝webpack-merge來實現拆分。

npm install webpack-merge --save-dev
複製代碼

拆分webpack.config.js

新建如下3個文件: webpack.common.js (公共配置) webpack.dev.js (開發環境配置) webpack.prod.js (生產環境配置) 將webpack.config.js代碼拆分後,可刪除webpack.config.js。

|- package.json
- |- webpack.config.js
+ |- webpack.common.js
+ |- webpack.dev.js
+ |- webpack.prod.js
  |- /dist
  |- /src
複製代碼

webpack.common.js保留公共配置的代碼

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const {CleanWebpackPlugin} = require('clean-webpack-plugin');
const webpack = require('webpack');
module.exports = {
    entry: {...},
    plugins: [...],
    output: {...}
};
複製代碼

webpack.dev.js保留開發環境配置的代碼

const merge = require('webpack-merge');
const common = require('./webpack.common');
module.exports = merge(common, {
    // 動態監測並實時更新頁面
    devServer: {
        contentBase: './dist',
        // 默認端口8080,可不填
        port: 8080,
        // 熱更新,無需刷新
        hot: true
    }
});
複製代碼

webpack.prod.js保留生產環境配置的代碼

const merge = require('webpack-merge');
const common = require('./webpack.common');
module.exports = merge(common, {
    // 方便追蹤源代碼錯誤
    //(若是不須要3.2小節的追蹤功能,能夠註釋掉下行代碼)
    devtool: 'source-map'
});
複製代碼

修改package.json:

"scripts": {
M      "build": "webpack --config webpack.prod.js --mode production",
M      "serve": "webpack-dev-server --open --config webpack.dev.js --mode development"
    },
複製代碼

5 集成公用JS庫(以jQuery爲例)

本節以jQuery爲例,講解如何引入公用JS庫。若是使用AngularJS、React或者Vue,建議使用官方的CLI工具。

5.1 安裝並集成jQuery

安裝jQuery:

npm install jquery --save
複製代碼

5.2 全局應用jQuery

jQuery是每一個頁面都要用的,在每一個頁面import太過於繁瑣,修改webpack.common.js進行全局配置:

...
+  const webpack = require('webpack');

    module.exports = {
        ...
        plugins: [
+           new webpack.ProvidePlugin({
+               $: 'jquery',
+               jQuery: 'jquery'
+           }),
            new CleanWebpackPlugin(),
            ...
複製代碼

5.3 使用jQuery

修改src/html/index.html,加入div,用於測試:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Webpack Demo</title>
</head>
<body>
    <div id="app">
        <div id="info"></div>
    </div>
</body>
</html>
複製代碼

修改src/js/index.js:

$('#info').text('jQuery正常使用');
複製代碼

執行npm run build,生成dist以下:

|- /dist
    |- index.html
    |- login.html
    |- /js
       |- index.js  <--jQuery代碼已集成到這裏
       |- login.js

複製代碼

login.js沒有jQuery代碼是由於login.js裏暫時還沒用到jQuery,webpack的打包機制是「確實使用了」纔會被真正打包進去。

若是咱們的項目有不少html靜態頁,每一個js都集成了jQuery,並且jQuery代碼基本不會變更,這樣就致使js文件冗餘,咱們能夠把jQuery單獨打包出來,能夠方便瀏覽器緩存,減小請求的js大小。

5.4 單獨打包jQuery

使用webpack的splitChunks來實現單獨打包。

修改webpack.common.js:

plugins: [
        ...
        // 設置html模板生成路徑
        new HtmlWebpackPlugin({
            filename: 'index.html',
            template: './src/html/index.html',
M           chunks: ['jquery', 'index']
        }),
        new HtmlWebpackPlugin({
            filename: 'login.html',
            template: './src/html/login.html',
M           chunks: ['jquery', 'login']
        }),
     ],
+    optimization: {
+       splitChunks: {
+           cacheGroups: {
+               commons: {
+                   test: /jquery/,
+                   name: 'jquery',
+                   chunks: 'all'
+               }
+           }
+       }
+   },
     // 編譯輸出配置
     output: {...}
複製代碼

執行npm run build,頁面運行正常,生成dist以下:

|- /dist
    |- index.html
    |- login.html
    |- /js
       |- index.js 
       |- login.js
+      |- jquery.js  <--jQuery已獨立出來
複製代碼

6 兼容IE8處理方式

若是要兼容IE8等低版本瀏覽器,在開發過程當中使用ES6等高版本js語法,會導低版本瀏覽器沒法運行。另外,jQuery只能使用1.x,要安裝低版本jQuery。(若是不須要兼容IE8,請直接跳過本章節)

首先,先安裝兼容IE6~8的jQuery。

npm install jquery-1x --save
複製代碼

修改webpack.common.js:

...
    plugins: [
            new webpack.ProvidePlugin({
M              $: 'jquery-1x',
M              jQuery: 'jquery-1x'
            }),
            ...
複製代碼

6.1 解決IE8「缺乏標識符」錯誤

如今build出來的代碼,IE8會在e.default代碼處報錯「缺乏標識符」。須要安裝uglifyjs-webpack-plugin。

npm install uglifyjs-webpack-plugin --save-dev
複製代碼

修改webpack.common.js

...
+  const UglifyJsPlugin = require('uglifyjs-webpack-plugin');

    module.exports = {
        ...
        optimization: {
            splitChunks: { ... },
+           minimizer: [
+               new UglifyJsPlugin({
+                   uglifyOptions: {
+                     ie8: true
+                   }
+               })
+           ]
         },
複製代碼

6.2 解決ES6轉ES5

若是使用ES6語法,例如箭頭函數,build會報錯不經過。要把ES6轉爲ES5,須要安裝如下插件(較多): babel-loader @babel/core @babel/preset-env @babel/plugin-transform-runtime @babel/plugin-transform-modules-commonjs @babel/runtime

npm install babel-loader @babel/core @babel/preset-env --save-dev
npm install @babel/plugin-transform-runtime @babel/plugin-transform-modules-commonjs --save-dev
npm install @babel/runtime --save
複製代碼

修改webpack.common.js,這裏代碼的做用是,在編譯時把js文件中ES6轉成ES5:

optimization: {...},
+   module: {
+      rules: [
+          {
+              test: /\.js$/,
+              exclude: /(node_modules|bower_components)/,
+              use: {
+                  loader: 'babel-loader',
+                  options: {
+                      presets: ['@babel/preset-env'],
+                      plugins: [
+                          '@babel/plugin-transform-runtime',
+                          '@babel/plugin-transform-modules-commonjs'
+                      ]
+                  }
+              }
+          }
+      ]
+   },
    // 編譯輸出配置
    output: {...}
複製代碼

如今執行npm run build,編譯經過。可是IE8下報錯「對象不支持bind屬性方法」,這是由於IE8不支持ES5,還須要引入es5-shim和es5-sham(見下節)。

6.3 解決IE8「對象不支持bind屬性方法」錯誤

嘗試了不少網上的方法,都沒有嘗試成功,最後乾脆用直接引用的方法來解決。

下載插件

先去官網 github.com/es-shims/es…

下載es5-shim.min.js和es5-sham.min.js

在src下建立static目錄,用於存放靜態資源,經過使用CopyWebpackPlugin讓static不被打包,直接copy到dist目錄下。

|- /src
   |- /css
      (略)
   |- /html
      |- index.html
      |- login.html
   |- /js
      (略)
   |- /static
      |- /js
         |- es5-shim.min.js
         |- es5-sham.min.js
複製代碼

而後,在src/html/index.html和src/html/login.html的裏直接引入

<head>
        <meta charset="UTF-8">
        <title>>Webpack Demo</title>
+       <script type="text/javascript" src="static/js/es5-shim.min.js"></script>
    </head>
複製代碼

es5-sham.min.js可在之後用到的時候再引入。

安裝插件copy-webpack-plugin

npm install --save-dev copy-webpack-plugin
複製代碼

修改webpack.common.js,代碼做用是將src/static直接copy到dist,並重命名爲static。

...
+   const CopyWebpackPlugin = require('copy-webpack-plugin');
    module.exports = {
        ...
        plugins: [
            ...
            new HtmlWebpackPlugin({
                filename: 'login.html',
                template: './src/html/login.html',
                chunks: ['jquery', 'login']
            }),
+           new CopyWebpackPlugin([
+               { from: './src/static', to: 'static' }
+           ])
複製代碼

執行npm run build,在IE8下能夠愉快的運行啦。

7 CSS及Stylus的使用

7.1 加載CSS和Stylus

本節以Stylus爲例,若是使用Sass/Less,能夠參考本方法。混用CSS是爲了同時掌握CSS使用方法。

安裝相關依賴包:

npm install style-loader css-loader --save-dev
npm install stylus-loader stylus --save-dev
複製代碼

如今src目錄以下:

|- /src
+    |- /css
+        |- /common
+           |- common.css
+           |- frame.css (這個文件@import common.css和reset.css)
+           |- reset.css
+        |- /pages
+           |- index.styl
+           |- login.styl
     |- /html
        |- index.html
        |- login.html
     |- /js
       (略)
複製代碼

css及styl內的樣式代碼,請自行補充,這裏再也不展現了。

index.js中引入樣式:

import '../css/common/frame.css';
import '../css/pages/index.styl';
複製代碼

login.js中引入樣式:

import '../css/common/frame.css';
import '../css/pages/login.styl';
複製代碼

修改webpack.common.js:

module.exports = {
        ...
        optimization: { ... }
+       module: {
+           rules: [
+              {
+                  test: /\.css$/,
+                  use: [
+                      'style-loader',
+                      'css-loader'
+                  ]
+              },
+              {
+                  test: /\.styl$/,
+                  use: [
+                      'style-loader',
+                      'css-loader',
+                      'stylus-loader'
+                  ]
+              }
+           ]
+       },
        ...
複製代碼

執行build後,樣式代碼會直接打包插入到html文件中。

7.2 分離樣式到css文件

如今咱們想把樣式經過link方式引入。

先安裝MiniCssExtractPlugin

npm install mini-css-extract-plugin --save-dev
複製代碼

而後修改webpack.common.js

···
+   const MiniCssExtractPlugin = require('mini-css-extract-plugin');

    module.exports = {
        plugins: [
           ...
+          new MiniCssExtractPlugin({
+              filename: 'css/[name].css'
+          }),
            new CopyWebpackPlugin([
                { from: './src/static', to: 'static' }
            ])
        ],
        module: {
            rules: [
                {
                    test: /\.css$/,
                    use: [
+                      // 將原來的style-loader替換
M                      MiniCssExtractPlugin.loader,
                        'css-loader'
                    ]
                },
                {
                    test: /\.styl$/,
                    use: [
+                      // 將原來的style-loader替換
M                      MiniCssExtractPlugin.loader,
                        'css-loader',
                        'stylus-loader'
                    ]
                }
                ···
複製代碼

執行npm run build,生成的dist以下:

|- /dist
   |- index.html
   |- login.html
+  |- /css
+     |- index.css
+     |- login.css
   |- /js
     (略)
複製代碼

index.css和login.css都包含了公用樣式,還能夠進一步優化,把公用樣式分離出來。

7.3 優化分離css公用樣式

修改webpack.common.js,使用正則,把src/css/common/下的css單獨打包並引用。

...
    plugins: [
        new HtmlWebpackPlugin({
            filename: 'index.html',
            template: './src/html/index.html',
M           chunks: ['style', 'jquery', 'index']
        }),
        new HtmlWebpackPlugin({
            filename: 'login.html',
            template: './src/html/login.html',
M           chunks: ['style', 'jquery', 'login']
        }),
        new MiniCssExtractPlugin({
            filename: 'css/[name].css'
        })
    ],
    optimization: {
        splitChunks: {
            cacheGroups: {
                commons: {
                    test: /jquery/,
                    name: 'jquery',
                    chunks: 'all'
                },
+               styles: {
+                   test: /[\\/]common[\\/].+\.css$/,
+                   name: 'style',
+                   chunks: 'all',
+                   enforce: true
+               }
            }
        }
    },
複製代碼

執行npm run build,生成的dist以下:

|- /dist
    |- index.html
    |- login.html
+   |- /css
+      |- index.css
+      |- login.css
       |- style.css <-- 公用css
    |- /js
       |- index.js
       |- login.js
       |- jquery.js
       |- style.js  <-- 怎麼會有這個?
複製代碼

發如今dist/js/目錄下會生成一個多餘的style.js,而且html也會引用這個多餘的js。這是webpack4的bug,從2016年到如今處於open狀態未解決,第三方插件都試過了,目前尚未解決,期待在webpack5中能夠解決。

能夠參看:github.com/webpack/web…

網上解決方案中涉及到的第三方插件:

disable-output-webpack-plugin

html-webpack-exclude-assets-plugin

remove-source-webpack-plugin

以上插件N久沒有更新了,在目前最新的webpack4.35.0中都沒法使用。

8 使用ejs將html模塊化

若是每一個頁面都有一個header,就能夠把header抽成html模塊,而後在須要的頁面引入。這裏經過ejs來實現。ejs本質仍是個html,只不過多了些模板語法。

安裝ejs-loader

npm install ejs-loader --save-dev
複製代碼

以index.html爲例,把index.html重命名爲index.ejs

修改webpack.common.js,支持ejs:

plugins: [
          ...
            new HtmlWebpackPlugin({
                filename: 'index.html',
+               // 這裏將html改爲ejs
M               template: './src/html/index.ejs',
                chunks: ['style', 'jquery', 'index']
            }),
            ...
    module: {
            rules: [
                ...
+               {
+                   test: /\.ejs/,
+                   use: ['ejs-loader'],
+               }
                ...
複製代碼

建立src/html/components/header/header.ejs

<div id="header" class="G-header">這是公用頭部</div>
複製代碼

在src/html/index.ejs引入便可。

...
    <div id="app">
+       <%= require('./components/header/header.ejs')() %>
        <div id="info"></div>
    </div>
    ...
複製代碼

9 加載圖片資源

本章節介紹如何在css和html中引用圖片。

安裝插件file-loader和url-loader,url-loader基於file-loader,因此兩個都要安裝。 (也能夠只使用file-loader,url-loader在file-loader的基礎上擴展了功能,好比能設置小於多少KB的圖片進行base64轉碼等)。

npm install file-loader url-loader --save-dev
複製代碼

9.1 css加載圖片

修改webpack.common.js

module: {
        rules: [
            ...
+           {
+              test: /\.(png|svg|jpg|gif|webp)$/,
+              use: [
+                  {
+                      loader: 'url-loader',
+                      options: {
+                          // 最終生成的css代碼中,圖片url前綴
+                          publicPath: '../images',
+                          // 圖片輸出的實際路徑(相對於dist)
+                          outputPath: 'images',
+                          // 當小於某KB時轉爲base64
+                          limit: 0
+                      }
+                  }
+              ]
+           }
             ...
         ]
     },
複製代碼

在src/images里加入圖片1.jpg

|- /src
   |- /css
       (略)
   |- /html
       (略)
+  |- /images
+     |- 1.jpg
   |- /js
      (略)
   |- /static
      (略)
複製代碼

在src/css/pages/index.styl加入代碼:

.bg-pic
    width: 200px
    height: 200px
    background: url(../../images/1.jpg) no-repeat
複製代碼

在src/html/index.ejs加入代碼:

<div id="app">
        <%= require('./components/header/header.ejs')() %>
        <div id="info"></div>
+       <div class="bg-pic"></div>
    </div>
複製代碼

執行npm run build,圖片可正常訪問,生成dist目錄以下:

|- /dist
    |- /css
      (略)
    |- /images
+      |- f0a89ff457b237711f8306a000204128.jpg
    |- /js
      (略)
    |- /static
      (略)
    |- index.html
    |- login.html
複製代碼

9.2 html加載圖片

html加載圖片的方式就是img加載圖片,須要提取html中的圖片地址,須要安裝插件html-loader

npm install html-loader --save-dev
複製代碼

在src/images里加入圖片2.jpg

|- /src
   |- /css
      (略)
   |- /html
      (略)
   |- /images
      |- 1.jpg
+     |- 2.jpg
   |- /js
      (略)
   |- /static
      (略)
複製代碼

修改webpack.common.js,這樣能夠把html中的圖片提取並打包。

module: {
        rules: [
            ...
+           {
+              test: /\.(html)$/,
+              use: {
+                  loader: 'html-loader',
+                  options: {
+                      attrs: ['img:src', 'img:data-src', 'audio:src'],
+                      minimize: true
+                  }
+              }
+           }
            ...
複製代碼

在src/html/index.ejs加入代碼:

<div id="app">
        <%= require('./components/header/header.ejs')() %>
        <div id="info"></div>
        <div class="bg-pic"></div>
+       <img src="${require('../images/2.jpg')}" alt="">
    </div>
複製代碼

執行npm run build,圖片已可正常訪問,生成dist目錄以下

|- /dist
   |- /css
      (略)
   |- /images
      |- f0a89ff457b237711f8306a000204128.jpg
+     |- dab63db25d48455007edc5d81c476076.jpg
   |- /js
      (略)
   |- /static
      (略)
   |- index.html
   |- login.html
複製代碼

可是發現html中img的圖片不能顯示。查看生成的代碼發現:

dist/index.html中的src爲../images/xxxx.jpg

dist/css/index.css中background的url也爲../images/xxxx.jpg

由於html和css的路徑差了一級,致使路徑不一致。所以須要區分html和css中的圖片路徑。

9.3 解決css和html中引用圖片路徑不一致的問題

修改webpack.common.js,將MiniCssExtractPlugin.loader改成對象的方式:

module: {
        rules: [
            ...
            {
                test: /\.css$/,
                use: [
M                  {
M                      loader: MiniCssExtractPlugin.loader,
M                      options: {
M                          // css中的圖片路徑增長前綴
M                          publicPath: '../'
M                      }
M                  },
                'css-loader'
                ]
            },
            {
                test: /\.styl$/,
                use: [
M                  {
M                      loader: MiniCssExtractPlugin.loader,
M                      options: {
M                          // css中的圖片路徑增長前綴
M                          publicPath: '../'
M                      }
M                  },
                    'css-loader',
                    'stylus-loader'
                ]
            },
            ...
            {
                test: /\.(png|svg|jpg|gif|webp)$/,
                use: [
                    {
                        loader: 'url-loader',
                        options: {
D                          // 最終生成的圖片路徑代碼 (刪除)
D                          // publicPath: '../images',  (刪除)
                            // 圖片輸出的實際路徑
                            outputPath: 'images',
                            // 當小於某KB時轉爲base64
                            limit: 0
                        }
                    }
                ]
            },
            ...
複製代碼

再執行npm run build,路徑顯示正常了。

10 加載iconfont

從阿里巴巴圖標網站 www.iconfont.cn/ 下載字體和樣式文件,導入到項目中,結構以下:

|- /src
   |- /css
      |- /common
         |- common.css
         |- frame.css
+        |- iconfont.css
         |- reset.css
      |- /pages
         |- index.styl
         |- login.styl
+  |- /fonts
+     |- iconfont.eot
+     |- iconfont.svg
+     |- iconfont.ttf
+     |- iconfont.woff
+     |- iconfont.woff2
   |- /html
       (略)
   |- /images
       (略)
   |- /js
       (略)
   |- /static
       (略)
複製代碼

src/css/common/frame.css裏要@import "iconfont.css",而後修改iconfont.css中每一個字體的路徑。

在src/html/index.ejs裏直接使用字體(字體樣式在iconfont網站定義):

<i class="G-iconfont G-ficon-cart"></i>
複製代碼

修改webpack.common.js,

module: {
        rules: [
            ...
+          {
+              test: /\.(woff|woff2|eot|ttf|svg)$/,
+              use: {
+                  loader: 'file-loader',
+                  options: {
+                      // 保留原文件名和後綴名
+                      name: '[name].[ext]',
+                      // 輸出到dist/fonts/目錄
+                      outputPath: 'fonts',
+                  }
+              }
+          }
        ]
    },
複製代碼

執行npm run build, 生成dist目錄以下:

|- /dist
   |- /css
      (略)
   |- /images
      (略)
+  |- /fonts
      |- iconfont.eot
      |- iconfont.svg
      |- iconfont.ttf
      |- iconfont.woff
   |- /js
      (略)
   |- /static
      (略)
   |- index.html
   |- login.html
複製代碼

沒有生成woff2文件,是由於css中沒有引用。

11 使用cnpm加速下載

npm有時下載速度很慢,能夠安裝cnpm,從國內淘寶鏡像下載,執行如下命令:

npm install -g cnpm --registry=https://registry.npm.taobao.org
複製代碼

之後npm直接替換成cnpm使用。

以上就是基於webpack4.x搭建標準前端工程的技術分享。

歡迎關注個人我的微信公衆號,隨時獲取最新文章^_^

相關文章
相關標籤/搜索