webpack 開發模式管理 Development

garynan發表於2019-03-17

webpack 開發模式管理 Development

GitHub 學習 Demo。

接下來將一些開發時的 webpack 配置。

warnning : 本指南中的工具僅用於開發,請避免在生產中使用它們!

先把 mode 屬性變為 development.

# webpack.config.js

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

  module.exports = {
+   mode: 'development',
    entry: {
      app: './src/index.js',
      print: './src/print.js'
    },
    plugins: [
      new CleanWebpackPlugin(['dist']),
      new HtmlWebpackPlugin({
        title: 'Development'
      })
    ],
    output: {
      filename: '[name].bundle.js',
      path: path.resolve(__dirname, 'dist')
    }
  };
複製程式碼

使用 source maps

當webpack捆綁您的原始碼時,很難找到錯誤和警告到其原始位置。因為此時錯誤都是從 bundle.js 裡丟擲的,而這是一個經過編譯的檔案。。。

JavaScript 提供 source maps ,能將編譯後的程式碼對映回原始原始碼。 如果錯誤源自b.js,源地圖將準確地告訴您。

這裡選用 devtool: 'inline-source-map' 選項達到這一目的。關於 devtool 的更多選項及其功能,請點連結閱讀。

# webpack.config.js

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

  module.exports = {
    mode: 'development',
    entry: {
      app: './src/index.js',
      print: './src/print.js'
    },
+   devtool: 'inline-source-map',
    plugins: [
      new CleanWebpackPlugin(['dist']),
      new HtmlWebpackPlugin({
        title: 'Development'
      })
    ],
    output: {
      filename: '[name].bundle.js',
      path: path.resolve(__dirname, 'dist')
    }
  };
  
# src/print.js
# 寫一段錯誤語法的程式碼

  export default function printMe() {
-   console.log('I get called from print.js!');
+   cosnole.log('I get called from print.js!');
  }
複製程式碼

編譯後回發現報錯:

Uncaught ReferenceError: cosnole is not defined
   at HTMLButtonElement.printMe (print.js:2)
複製程式碼

選擇一個 Development Tool

現在的程式,每次需要檢視新的結果,都要重新編譯一次,非常的麻煩。
有幾種方法可以實現,你程式碼發生變化時,自動從新編譯:

  • wepback 的 Watch Mode (觀察模式)
  • webpack-dev-server
  • webpack-dev-middleware

大多數情況下都會選用 webpack-dev-server。但接下來每個都會講到。

Watch Mode

使用 webpack 的命令列選項 --watch 實現。
新增一段 npm script :

  {
    "name": "development",
    "version": "1.0.0",
    "description": "",
    "main": "webpack.config.js",
    "scripts": {
      "test": "echo \"Error: no test specified\" && exit 1",
+     "watch": "webpack --watch",
      "build": "webpack"
    },
    "keywords": [],
    "author": "",
    "license": "ISC",
    "devDependencies": {
      "clean-webpack-plugin": "^0.1.16",
      "css-loader": "^0.28.4",
      "csv-loader": "^2.1.1",
      "file-loader": "^0.11.2",
      "html-webpack-plugin": "^2.29.0",
      "style-loader": "^0.18.2",
      "webpack": "^3.0.0",
      "xml-loader": "^1.2.1"
    }
  }
複製程式碼

現在從命令列執行npm run watch,看看webpack如何編譯你的程式碼。 您可以看到它不會退出命令列,因為指令碼當前正在檢視您的檔案。

此時當你儲存程式碼修改的時候,就會促發重新編譯。

但這個功能的缺點就是,該功能僅是監聽到程式碼變化後重新編譯,但瀏覽器不會自定更新變化。webpack-dev-server 可以解決這個問題。

webpack-dev-server

webpack-dev-server為您提供了一個簡單的Web伺服器,並能夠使用實時重新載入。 我們來設定一下:

依賴
npm install --save-dev webpack-dev-server
複製程式碼
修改配置
# webpack.config.js

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

  module.exports = {
    mode: 'development',
    entry: {
      app: './src/index.js',
      print: './src/print.js'
    },
    devtool: 'inline-source-map',
+   devServer: {
+     contentBase: './dist'
+   },
    plugins: [
      new CleanWebpackPlugin(['dist']),
      new HtmlWebpackPlugin({
        title: 'Development'
      })
    ],
    output: {
      filename: '[name].bundle.js',
      path: path.resolve(__dirname, 'dist')
    }
  };
複製程式碼

tips :
webpack-dev-server在編譯後不會寫任何輸出檔案。 相反,它將捆綁檔案儲存在記憶體中併為它們提供服務,就好像它們是安裝在伺服器根路徑上的真實檔案一樣。

如果您的頁面希望在不同的路徑中找到捆綁包檔案,則可以使用dev伺服器配置中的publicPath選項進行更改。

修改 npm script
# package.json

 {
    "name": "development",
    "version": "1.0.0",
    "description": "",
    "main": "webpack.config.js",
    "scripts": {
      "test": "echo \"Error: no test specified\" && exit 1",
      "watch": "webpack --watch",
+     "start": "webpack-dev-server --open",
      "build": "webpack"
    },
    "keywords": [],
    "author": "",
    "license": "ISC",
    "devDependencies": {
      "clean-webpack-plugin": "^0.1.16",
      "css-loader": "^0.28.4",
      "csv-loader": "^2.1.1",
      "file-loader": "^0.11.2",
      "html-webpack-plugin": "^2.29.0",
      "style-loader": "^0.18.2",
      "webpack": "^3.0.0",
      "xml-loader": "^1.2.1"
    }
  }
複製程式碼

現在我們可以從命令列執行npm start,我們將看到我們的瀏覽器自動載入我們的頁面。 如果您現在更改任何原始檔並儲存它們,Web 伺服器將在編譯程式碼後自動重新載入。

關於 webpack-dev-server 的更多選項

webpack-dev-middleware

webpack-dev-middleware是一個包裝器,它將 webpack 處理的檔案傳送到伺服器。 這在webpack-dev-server內部使用,但是它可以作為單獨的包提供,以便在需要時允許更多自定義設定。 我們將看一個將webpack-dev-middlewareexpress server伺服器相結合的示例。

安裝依賴
npm install --save-dev express webpack-dev-middleware
複製程式碼
修改配置

現在我們需要對webpack配置檔案進行一些調整,以確保中介軟體能夠正常執行:

# webpack.config.js

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

  module.exports = {
    mode: 'development',
    entry: {
      app: './src/index.js',
      print: './src/print.js'
    },
    devtool: 'inline-source-map',
    devServer: {
      contentBase: './dist'
    },
    plugins: [
      new CleanWebpackPlugin(['dist']),
      new HtmlWebpackPlugin({
        title: 'Output Management'
      })
    ],
    output: {
      filename: '[name].bundle.js',
      path: path.resolve(__dirname, 'dist'),
+     publicPath: '/'
    }
  };
複製程式碼

publicPath 將在我們的伺服器指令碼中使用,以確保在http:// localhost:3000上正確提供檔案。 我們稍後會指定埠號。 下一步是設定我們的自定義express server伺服器:

建立 server
  webpack-demo
  |- package.json
  |- webpack.config.js
+ |- server.js
  |- /dist
  |- /src
    |- index.js
    |- print.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);

// Tell express to use the webpack-dev-middleware and use the webpack.config.js
// configuration file as a base.
app.use(webpackDevMiddleware(compiler, {
  publicPath: config.output.publicPath
}));

// Serve the files on port 3000.
app.listen(3000, function () {
  console.log('Example app listening on port 3000!\n');
});
複製程式碼
現在新增一個npm script,使其更容易執行伺服器:
# package.json

  {
    "name": "development",
    "version": "1.0.0",
    "description": "",
    "main": "webpack.config.js",
    "scripts": {
      "test": "echo \"Error: no test specified\" && exit 1",
      "watch": "webpack --watch",
      "start": "webpack-dev-server --open",
+     "server": "node server.js",
      "build": "webpack"
    },
    "keywords": [],
    "author": "",
    "license": "ISC",
    "devDependencies": {
      "clean-webpack-plugin": "^0.1.16",
      "css-loader": "^0.28.4",
      "csv-loader": "^2.1.1",
      "express": "^4.15.3",
      "file-loader": "^0.11.2",
      "html-webpack-plugin": "^2.29.0",
      "style-loader": "^0.18.2",
      "webpack": "^3.0.0",
      "webpack-dev-middleware": "^1.12.0",
      "xml-loader": "^1.2.1"
    }
  }
複製程式碼

執行 npm run server,瀏覽器開啟 http:// localhost:3000。 您應該看到您的webpack應用程式正在執行並執行!

但是,你會發現更新程式碼時只會重新編譯。如果需要熱更新功能需要自己配置你得伺服器指令碼。

這種自定義開發伺服器的方式非常靈活,但需要你具備一定的 node.js 基礎。

NEXT

既然您已經學會了如何自動編譯程式碼並執行一個簡單的開發伺服器,下一步就來認識 Hot Module Replacement 熱模組切換

相關文章