Webpack筆記(三):管理文件輸出與自動構(gòu)建

一、管理文件輸出

項目結(jié)構(gòu):
webpack-test
  |- package.json
  |- webpack.config.js
  |- dist
    |- index.html
  |- src
    |- index1.js
    |- index2.js
  |- node_modules

index1.js

export default function() {
  console.log('this is index1.js!');
}

index2.js

export default function() {
  console.log('this is index2.js!');
}

index.html

<!doctype html>
<html>
  <head>
    <title>Webpack Test</title>
  </head>
  <body>
    <script src="./a.bundle.js"></script>
    <script src="./b.bundle.js"></script>
  </body>
</html>

webpack.config.js

const path = require('path');

module.exports = {
  entry: {
    a: './src/index1.js',
    b: './src/index2.js'
  },
  output: {
    filename: '[name].bundle.js',
    path: path.resolve(__dirname, 'dist')
  }
}

npm script中添加腳本命令:

"scripts": {
  "build": "webpack",
}
使用HtmlWebpackPlugin

運行命令,就會發(fā)現(xiàn)dist目錄下生成了a.bundle.js和b.bundle.js。但如果,更改配置中的入口文件的名稱,相應的index.html也要修改,這就會很麻煩。HtmlWebpackPlugin插件在構(gòu)建時每次都創(chuàng)建一個index.html替代之前的index.html,新創(chuàng)建的html文件中包含使用script標簽的body中的所有webpack包。這對bundle名稱在每次編譯之后都變化(如以哈希值命名)的情況下很有效。

安裝

npm install --save-dev html-webpack-plugin

修改webpack.config.js

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

  module.exports = {
    entry: {
-     a: './src/index1.js',
-     b: './src/index2.js'
+     1: './src/index1.js',
+     2: './src/index2.js'
    },
+   plugins: [
+     new HtmlWebpackPlugin({
+       title: 'Webpack Test'  // 生成的html文件的標題
+     })
+   ],
    output: {
      filename: '[name].bundle.js',
      path: path.resolve(__dirname, 'dist')
    }
  };

運行 npm run build,就會發(fā)現(xiàn)HtmlWebpackPlugin創(chuàng)建了一個新的index.html,而且包含新的bundle。

使用ExtractTextWebpackPlugin

ExtractTextWebpackPlugin插件會將所有入口chunk中的.css文件移動到獨立分離的 CSS 文件,并插入到index.html文件的 <link>標簽中。它可以跟js bundle并行加載。

安裝

npm install --save-dev extract-text-webpack-plugin

在src目錄下添加index1.css和index2.css:

.index1: {
  color: red;
}
.index2: {
  color: red;
}

然后在index1.js和index2.js里分別引入css文件:
index1.js:

import './index1.css';

index2.js:

import './index2.css';

修改webpack.config.js:

  const path = require('path');
  const HtmlWebpackPlugin = require('html-webpack-plugin');
+ const ExtractTextPlugin= require('extract-text-webpack-plugin');

  module.exports = {
    entry: {
      1: './src/index1.js',
      2: './src/index2.js'
    },
    plugins: [
+     new ExtractTextPlugin('[name].css'),     // 每個入口 chunk 都生成一個對應的文件
      new HtmlWebpackPlugin({
        title: 'Webpack Test'
      })
    ],
    output: {
      filename: '[name].bundle.js',
      path: path.resolve(__dirname, 'dist')
    },
+   module: {
+     rules: [{
+       test: /\.css$/,
+       use: ExtractTextPlugin.extract({
+         fallback: 'style-loader',  // 應用于當css沒有被提取的時候
+         use: 'css-loader' // 用于將css文件轉(zhuǎn)換成一個導出模塊
+       })
+     }]
+   }
  };

運行 npm run build,就會發(fā)現(xiàn)index.html中新增了兩個 <link>標簽。

使用CleanWebpackPlugin

如果修改入口文件名稱再進行構(gòu)建,則會導致dist目錄下遺留上一次的bundle文件等。所以dist目錄下多出了很多不必要的文件,應該先清理掉。

安裝

npm install clean-webpack-plugin --save-dev

修改webpack.config.js:

  const path = require('path');
  const HtmlWebpackPlugin = require('html-webpack-plugin');
  const ExtractTextPlugin= require('extract-text-webpack-plugin');
+ const CleanWebpackPlugin = require('clean-webpack-plugin');

  module.exports = {
    entry: {
      1: './src/index1.js',
      2: './src/index2.js'
    },
    plugins: [
+    new CleanWebpackPlugin(['dist']), //清空dist目錄
     new ExtractTextPlugin('[name].css'),     // 每個入口 chunk 都生成一個對應的文件
      new HtmlWebpackPlugin({
        title: 'Webpack Test'
      })
    ],
    output: {
      filename: '[name].bundle.js',
      path: path.resolve(__dirname, 'dist')
    },
    module: {
      rules: [{
        test: /\.css$/,
        use: ExtractTextPlugin.extract({
          fallback: 'style-loader',  // 應用于當css沒有被提取的時候
          use: 'css-loader'  // 用于將css文件轉(zhuǎn)換成一個導出模塊
        })
      }]
    }
  };

運行 npm run build,就會發(fā)現(xiàn)dist目錄下只剩下新構(gòu)建的文件。

二、自動構(gòu)建

每次修改項目文件之后,都要運行 npm run build 命令去重新構(gòu)建十分繁瑣。而webpack提供了三種方案在修改文件之后進行自動構(gòu)建:

  1. 觀察模式(Watch Mode)
  2. webpack-dev-server (多數(shù))
  3. webpack-dev-middleware
1. 觀察模式

在 npm script 腳本中添加命令:

"watch": "webpack --watch",

然后運行 npm run watch,會看到Webpack is watching the files…且命令行不會退出,srcipt腳本仍然在觀察文件。使用觀察模式需要手動刷新瀏覽器才能看到修改后的效果。

2. webpack-dev-server

webpack-dev-server提供了簡單的web服務器,并實時重新加載。
安裝 webpack-dev-server

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

修改webpack.config.js,添加devServer配置:

const path = require('path');

module.exports = {
  ...
  devServer: {
    contentBase: 'some/path',  // 可訪問文件的路徑,告訴服務器從哪里提供內(nèi)容
    port: 9000 // 端口號
  }
  ...
}

更多devServer配置

在npm script腳本中添加命令:

"start": "webpack-dev-server --open", // open參數(shù)可以讓服務器在啟動時打開瀏覽器

運行 npm run start命令,就會看到瀏覽器自動跳轉(zhuǎn)到http://localhost:9000/,修改源文件會讓瀏覽器重新刷新。

3. webpack-dev-middleware

webpack-dev-middleware是一個與webpack的compiler綁定的中間件,可以在express服務中使用。
它通過watch mode以實現(xiàn)對變更文件的監(jiān)控,然后自動打包編譯進內(nèi)存中,減少打包進本地磁盤的時間。webpack-dev-server在內(nèi)部使用了它。

安裝

npm install --save-dev express webpack-dev-middleware

修改webpack.config.js

  const path = require('path');
  const HtmlWebpackPlugin = require('html-webpack-plugin');
  const ExtractTextPlugin= require('extract-text-webpack-plugin');
  const CleanWebpackPlugin = require('clean-webpack-plugin');

  module.exports = {
    entry: {
      1: './src/index1.js',
      2: './src/index2.js'
    },
    plugins: [
     new CleanWebpackPlugin(),
     new ExtractTextPlugin('[name].css'),     // 每個入口 chunk 都生成一個對應的文件
      new HtmlWebpackPlugin({
        title: 'Webpack Test'
      })
    ],
    output: {
      filename: '[name].bundle.js',
      path: path.resolve(__dirname, 'dist'),
+     publicPath: '/'
    },
    module: {
      rules: [{
        test: /\.css$/,
        use: ExtractTextPlugin.extract({
          fallback: 'style-loader',
          use: 'css-loader'
        })
      }]
    }
  };

設置自定義的 express 服務:

webpack-test
  |- package.json
  |- webpack.config.js
+ |- server.js
  |- dist
    |- index.html
  |- src
    |- index1.js
    |- index2.js
  |- node_modules

server.js

const express = require('express');
const webpack = require('webpack');
const webpackDevMiddleware = require('webpack-dev-middleware');

const app = express();
const config = require('./webpack.config.js');
const compiler = webpack(config);

app.use(webpackDevMiddleware(compiler, {
  publicPath: config.output.publicPath
}));

app.listen(3000, function () {
  console.log('listening on port 3000');
});

為了看到頁面效果,修改index1.js:

function write() {
  document.write('hello webpack-dev-middleware');
}

write();

修改package.json,在script腳本中添加命令:

"server": "node server.js",

運行 npm run server,構(gòu)建成功后,在瀏覽器中打開http://localhost:3000,就會看到頁面。修改源文件,然后刷新瀏覽器,就會看到修改后的結(jié)果。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容