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

webpack的基本使用

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

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

安裝

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

首先本身環境中安裝了有node(自帶npm)。若是你的項目中沒有package.json,那麼須要使用npm init。前端

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

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

咱們如今來使用npm來安裝webpack,能夠做爲一個全局的命令來使用:java

npm install webpack webpack-cli -g 

其中webpack-cli是使用webpack的命令行工具。在 4.x 版本以後再也不做爲 webpack 的依賴了,咱們使用時須要單獨安裝這個工具。node

更多的時候咱們是把webpack做爲項目的依賴來安裝使用的。webpack

npm install webpack webpack-cli -D 

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

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

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

代碼以下:

"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,以便使用 ES六、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。

相關文章
相關標籤/搜索