webpack4.x筆記-配置基本的前端開發環境(一)


webpack的基本使用

webpack 本質上是一個打包工具,它會根據代碼的內容解析模塊依賴,幫助我們把多個模塊的代碼打包。借用 webpack 官網的圖片:

雖然webpack4.x的版本可以零配置開始構建,但是在實際的項目中需要其它的一些功能,還是需要一個配置文件。

安裝

下面一步一步講解配置一個基本的前端開發環境過程。

首先自己環境中安裝了有node(自帶npm)。如果你的項目中沒有package.json,那么需要使用npm init。

會在項目下生成一個package.json文件,其中會有如下代碼:

{
  "name": "test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}

我們現在來使用npm來安裝webpack,可以作為一個全局的命令來使用:

npm install webpack webpack-cli -g 

其中webpack-cli是使用webpack的命令行工具。在 4.x 版本之后不再作為 webpack 的依賴了,我們使用時需要單獨安裝這個工具。

更多的時候我們是把webpack作為項目的依賴來安裝使用的。

npm install webpack webpack-cli -D 

package.json文件就會多了如下配置:

"devDependencies": {
    "webpack": "^4.27.1",
    "webpack-cli": "^3.1.2"
  }

我們在package.json中添加一個npm scripts:

代碼如下:

"scripts": {
    "build": "webpack --mode production"
  },
  "devDependencies": {
    "webpack": "^4.27.1",
    "webpack-cli": "^3.1.2"
  }

然后我們創建一個'./src/index.js',其中index.js中的代碼任意寫,如:

export default {
    a:'字符串'
}

然后執行npm run build后會在項目下增加了一個dist文件夾,里面存放了webpack構建好的main.js文件。

因為是作為項目依賴進行安裝,所以不會有全局的命令,npm 會幫助我們在當前項目依賴中尋找對應的命令執行,如果是全局安裝的 webpack,直接執行webpack --mode production就可以。

webpack重要的幾個概念

webpack 的幾個重要的概念:入口,loader,plugin,輸出。

入口

所謂入口,就是webpack的構建入口。webpack會讀取這個文件,並從它這兒開始解析依賴,然后進行打包。如上面操作,一開始webpack默認的構建入口就是'./src/index.js'

在我們的項目中,如果是單頁面應用,一般就只有一個入口;如果是多頁面,那么就會配置成一個頁面一個構建入口。

入口可以使用entry字段來設置,webpack支持配置多個入口進行構建打包:

module.exports = {
  entry: './src/index.js' 
}

// 上述配置等同於
module.exports = {
  entry: {
    main: './src/index.js'
  }
}

// 或者配置多個入口
module.exports = {
  entry: {
    foo: './src/page-foo.js',
    bar: './src/page-bar.js', 
    // ...
  }
}

// 使用數組來對多個文件進行打包
module.exports = {
  entry: {
    main: [
      './src/foo.js',
      './src/bar.js'
    ]
  }
}

最后的例子,可以理解為多個文件作為一個入口,webpack 會解析兩個文件的依賴后進行打包。

loader

webpack 中提供一種處理多種文件格式的機制,便是使用 loader。我們可以把 loader 理解為是一個轉換器,負責把某種文件格式的內容轉換成 webpack 可以支持打包的模塊。

舉個例子,比如你的入口文件index.js引入了css樣式,那么構建的時候就需要用css-loader來處理這些.css文件,同時還需要style-loader。最終打包的結果就是把不同類型的文件都解析成js代碼,以便在打包后能在瀏覽器中運行。

當我們需要使用不同的 loader 來解析處理不同類型的文件時,我們可以在module.rules字段下配置相關的規則,比如使用babel來轉化js代碼:

module: {
  // ...
  rules: [
    {
      test: /\.jsx?/, // 匹配文件路徑的正則表達式,通常我們都是匹配文件類型后綴
      include: [
        path.resolve(__dirname, 'src') // 指定哪些路徑下的文件需要經過 loader 處理
      ],
      use: 'babel-loader', // 指定使用的 loader
    },
  ],
}

后面有筆記會詳細記錄下loader的使用以及怎樣開發loader。

plugin

在webpack的構建工作中,除了用loader來處理模塊代碼的轉換,剩下的工作就是用plugin來完成,下面列舉常用的幾個:

  • 壓縮JS代碼:uglifyjs-webpack-plugin
  • 關聯JS生成html頁面:html-webpack-plugin
  • 生成CSS文件: extract-text-webpack-plugin
  • 定義環境變量:DefinePlugin

JS代碼壓縮配置如下:

const UglifyPlugin = require('uglifyjs-webpack-plugin')

module.exports = {
  plugins: [
    new UglifyPlugin()
  ],
}

輸出

webpack 的輸出即指 webpack 最終構建出來的靜態文件。構建結果的文件名、路徑等都是可以配置的,使用output字段:

module.exports = {
  // ...
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js',
  },
}

// 或者多個入口生成不同文件
module.exports = {
  entry: {
    foo: './src/foo.js',
    bar: './src/bar.js',
  },
  output: {
    filename: '[name].js',
    path: __dirname + '/dist',
  },
}

// 路徑中使用 hash,每次構建時會有一個不同 hash 值,避免發布新版本時線上使用瀏覽器緩存
module.exports = {
  // ...
  output: {
    filename: '[name].js',
    path: __dirname + '/dist/[hash]',
  },
}

我們剛開始構建的webpack,默認的構建結果就是'./dist/main.js'

一個簡單的webpack配置例子

上面總結了幾個webpack的重要概念后,來看一個簡單的配置例子,webpack運行時默認讀取項目下的webpack.config.js文件作為配置,那么我們現在就在項目下創建一個webpack.config.js文件:

const path = require('path')
const UglifyPlugin = require('uglifyjs-webpack-plugin') //js壓縮插件

module.exports = {
    entry:'./src/index.js',
    
    output:{
        path:path.resolve(__dirname,'dist'),
        filename:'bundle.js'
    },
    
    module:{
        rules:[
            {
                test:/\.jsx?/,//匹配js,jsx文件
                include:[
                    path.resolve(__dirname,'src')
                ],
                use:'babel-loader'
            }
        ]
    },
    
    // 代碼模塊路徑解析的配置
    resolve: {
        modules: [
          "node_modules",
          path.resolve(__dirname, 'src')
        ],

        extensions: [".wasm", ".mjs", ".js", ".json", ".jsx"],
    },
    
    plugins:[
        new UglifyPlugin() //使用uglifyjs-webpack-plugin壓縮JS代碼
        //根據上面第一次的構建,你會發現webpack默認使用了JS的代碼壓縮插件
        //這其實也是命令中的 --mode production的效果
    ]
}

當你直接運行npm run build命令的時候,會報錯Cannot find module 'uglifyjs-webpack-plugin'。這兒你需要安裝如下內容:

  • 1.npm install uglifyjs-webpack-plugin --save-dev
  • 2.npm install -D babel-loader@7 babel-core babel-preset-env webpack
  • 3.最后執行npm run build能看到在dist文件夾下生成了一個bundle.js構建完成的文件。

vue腳手架vue-cli的webpack配置

vue-cli 使用 webpack 模板生成的項目文件中,webpack 相關配置存放在 build 目錄下。現在的腳手架vue-cli的webpack好像還是用的webpack3.x版本,要注意下版本區別。

構建基本的前端開發環境

 我們構建基本的前端開發環境需要做哪些事情:

  • 構建我們發布需要的 HTML、CSS、JS 文件
  • 使用 CSS 預處理器來編寫樣式
  • 處理和壓縮圖片
  • 使用 Babel 來支持 ES 新特性
  • 本地提供靜態服務以方便開發調試

下面圍繞這些要求要構建開發環境。

JS關聯HTML頁面html-webpack-plugin

當我們構建打包完成生成了JS文件,怎樣把JS文件跟html頁面相關聯呢,也就是html怎樣引入js文件。當然可以使用script標簽引入js文件,但是如果打包構建的js路徑變化或者使用了hash命名,那么直接引入js文件就不合理了,這時就需要使用html-webpack-plugin

把html-webpack-plugin安裝到項目依賴中去:

npm install html-webpack-plugin -D 

首先自己按照下列目錄創建模板html文件,‘./src/assets/index.html’,html內容隨便寫,如下:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>這是構建的第一個web頁面</title>
    </head>
    <body>
    </body>
</html>

將html-webpack-plugin配置到webpack.config.js中的plugins列表中:

module.exports = {
  // ...
  plugins: [
    new HtmlWebpackPlugin({
      filename: 'index.html', // 配置輸出文件名和路徑
      template: 'assets/index.html', // 配置文件模板
    }),
  ],
}

這樣,通過 html-webpack-plugin 就可以將我們的頁面和構建 JS 關聯起來,這樣將會產生一個包含以下內容的文件dist/index.html。打開index.html可以看到構建后的代碼如下:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>這是構建的第一個web頁面</title>
    </head>
    <body>
    <script type="text/javascript" src="bundle.js"></script></body>
</html>

詳細了解可參考文檔html-webpack-plugin, 官網提供的例子html-webpack-plugin/examples/

 構建CSS

我們構建CSS需要使用css-loader和style-loader。

module.exports = {
  module: {
    rules: [
      // ...
      {
        test: /\.css/,
        include: [
          path.resolve(__dirname, 'src'),
        ],
        use: [
          'style-loader',
          'css-loader',
        ],
      },
    ],
  }
}

注:style-loader 和 css-loader 都是單獨的 node package,需要安裝。

我們創建一個index.css,在index.js中引入:

import './index.css'

index.css里面隨便編寫一段css代碼:

.title{
    font-weight: bold;
    font-size:20px;
    color:red;
}

模板index.html改成如下:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title><%= htmlWebpackPlugin.options.title %></title>
    </head>
    <body>
        <div class="title">這是一個主題</div>
    </body>
</html>

安裝style-loader與css-loader:

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

現在執行npm run build,然后去看生成的index.html,效果有了,css樣式添加上了。但是並沒有生成css文件。

解釋下css-loader跟style-loader的作用:

  • css-loader 負責解析 CSS 代碼,主要是為了處理 CSS 中的依賴,例如@importurl()等引用外部文件的聲明;
  • style-loader 會將 css-loader 解析的結果轉變成 JS 代碼,運行時動態插入style標簽來讓 CSS 代碼生效。

如果需要單獨把 CSS 文件分離出來,我們需要使用extract-text-webpack-plugin.

由於webpack4.x的extract-text-webpack-plugin版本還沒有發布正式版,安裝的時候需要指定使用它的 alpha 版本:

npm install extract-text-webpack-plugin@next -D

配置:

const ExtractTextPlugin = require('extract-text-webpack-plugin')

module.exports = {
  // ...
  module: {
    rules: [
      {
        test: /\.css$/,
        // 因為這個插件需要干涉模塊轉換的內容,所以需要使用它對應的 loader
        use: ExtractTextPlugin.extract({ 
          fallback: 'style-loader',
          use: 'css-loader',
        }), 
      },
    ],
  },
  plugins: [
    // 引入插件,配置文件名,這里同樣可以使用 [hash]
    new ExtractTextPlugin('index.css'),
  ],
}

然后就會在dist文件夾下多生成一個index.css文件。詳細可參考:extract-text-webpack-plugin

CSS 預處理器

通常我們在編寫css的時候,經常使用less或者sass等css預處理器,我們以less為例,我們把index.css改成index.less如下:

@fontSize:20px;
.title{
    font-weight: bold;
    font-size:@fontSize;
    color:red;
}

安裝less-loader,官網文檔對應loader:

npm install --save-dev less-loader less

 對應的配置文件修改為:

module.exports = {
  // ...
  module: {
    rules: [
      {
        test: /\.less$/,
        // 因為這個插件需要干涉模塊轉換的內容,所以需要使用它對應的 loader
        use: ExtractTextPlugin.extract({ 
          fallback: 'style-loader',
          use: [
            'css-loader', 
            'less-loader',
          ],
        }), 
      },
    ],
  },
  // ...
}

 處理圖片文件file-loader及增強版url-loader

file-loader

雖然css-loader會解析樣式中用url()引用的文件路徑,但是圖片有jpg/png/gif格式,webpack處理不了,需要使用一個loader配置才行,這就用到了file-loader。

file-loader 可以用於處理很多類型的文件,它的主要作用是直接輸出文件,把構建后的文件路徑返回。

配置如下:

module.exports = {
  // ...
  module: {
    rules: [
      {
        test: /\.(png|jpg|gif)$/,
        use: [
          {
            loader: 'file-loader',
            options: {},
          },
        ],
      },
    ],
  },
}

安裝file-loader,官方文檔file-loader:

npm install --save-dev file-loader

我在index.js引入一張圖片:

import '../assets/a.jpg'

運行結果默認在dist目錄下生成了78414f2de9fc47d29f335727a717bc3d.jpg。默認情況下,生成的文件的文件名就是文件內容的 MD5 哈希值並會保留所引用資源的原始擴展名。

當然也可以配置輸出路徑,文件名稱等,如下:

{
    test:/\.(jpg|png|gif)$/,
    use:[
        {
            loader:'file-loader',
            options:{
                name: '[path][name].[ext]',
                outputPath: 'images/'
            }
        }
    ]
}        

url-loader

 安裝url-loader,詳細文檔請參考官網url-loader

url-loader功能類似於file-loader,但是在文件大小(單位 byte)低於指定的限制時,可以返回一個 DataURL。

npm install --save-dev url-loader

配置:

module.exports = {
  module: {
    rules: [
      {
        test: /\.(png|jpg|gif)$/i,
        use: [
          {
            loader: 'url-loader',
            options: {
              limit: 8192
            }
          }
        ]
      }
    ]
  }
}

使用 Babel

Babel是一個讓我們能夠使用 ES 新特性的 JS 編譯工具,我們可以在 webpack 中配置 Babel,以便使用 ES6、ES7 標准來編寫 JS 代碼。

前面已經寫過配置了,代碼如下:

module.exports = {
  // ...
  module: {
    rules: [
      {
        test: /\.jsx?/, // 支持 js 和 jsx
        include: [
          path.resolve(__dirname, 'src'), // src 目錄下的才需要經過 babel-loader 處理
        ],
        loader: 'babel-loader',
      },
    ],
  },
}

Babel 的相關配置可以在目錄下使用 .babelrc 文件來處理,詳細參考 Babel 官方文檔 .babelrc

使用 webpack-dev-server啟動靜態服務

我們可以使用 webpack-dev-server 在本地開啟一個簡單的靜態服務來進行開發。

安裝webpack-dev-server:

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

然后添加啟動命令到 package.json 中:

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

然后運行npm run start,然后就可以訪問 http://localhost:8080/ 來查看你的頁面了。默認是訪問 index.html,如果是其他頁面要注意訪問的 URL 是否正確。

總結

根據上面的配置,我們已經完成了配置一個簡單的前端開發環境,實現了:構建 HTML、CSS、JS 文件、使用 CSS 預處理器來編寫樣式、處理和壓縮圖片、使用 Babel、方便開發調試的靜態服務。下面的筆記會記錄webpack的一些細節來更好的了解webpack。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM