用Webpack将Express进行打包【第一部分】
我按照文章的指示试试看。
使用Google翻译做了一个中文译文,仅供参考:
创建一个具有开发和生产构建的Node Express-Webpack应用程序并进行翻译。如果有错误,请指正。
如果原文中没有评论,可以使用引用方式进行书写。
我想做的东西
将开发构建和生产构建分开。
開發版本
-
- ES6+のトランスパイル。
-
- lint
-
- 単体テスト
-
- カバレッジレポート
-
- HMR(Hot Module Reloading)
-
- minifyしない
- imageやcssをBase64エンコードせずに保持する。
生产建设
-
- minifyする。
-
- uglify する。
- imageとcssはBase64エンコードする。
为了避免不必要的导入,开发和生产分别使用不同的Express服务器文件和Webpack配置文件进行管理。
技術堆栈
-
- Express — server
-
- Webpack 4 — bundling
-
- Jest — testing
-
- Babel — ES6+ transpilation
-
- ESlint — Linting
-
- Webpack Dev Middleware — Bundle code in memory instead of in a file
-
- Webpack Hot Middleware — Enables Hot Module Reloading (HMR)
-
- UglifyJS — uglifies code
- mini-css-extract-plugin — minifies CSS
好的,让我们开始吧。
步骤1:快速服务器
我的验证环境
-
- macOS Sierra 10.12.6
-
- Node v10.0.0
-
- NPM 6.0.0
-
- Webpack 4
- Express 4.16.3
自己的验证环境
-
- Windows8.1
-
- Node v10.14.1
-
- NPM 6.4.1
-
- Webpack 4
- Express 4.16.4
建立验证环境目录
mkdir express-webpack
cd express-webpack
创建 package.json 文件
npm init -y
安装Express
npm install --save express
请在 package.json 文件中添加以下内容。
"scripts": {
"start": "node ./server.js"
},
让我们将基本的Express服务器文件写入项目的根目录server.js,并测试其是否正常工作。
const path = require('path')
const express = require('express')
const app = express(),
DIST_DIR = __dirname,
HTML_FILE = path.join(DIST_DIR, 'index.html')
app.use(express.static(DIST_DIR))
app.get('*', (req, res) => {
res.sendFile(HTML_FILE)
})
const PORT = process.env.PORT || 8080
app.listen(PORT, () => {
console.log(`App listening to ${PORT}....`)
console.log('Press Ctrl+C to quit.')
})
当然,创建一个简单美观的 HTML 文件,命名为 “Hello”(index.html)。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Express and Webpack App</title>
<link rel="shortcut icon" href="#">
</head>
<body>
<h1>Expack</h1>
<p class="description">Express and Webpack Boilerplate App</p>
</body>
</html>
现在,为了测试它的运行,执行 npm start 并导航到 http://localhost:8080。页面应该正确显示 HTML。
步骤2:安装并启用Webpack
安装与webpack相关的软件包。
webpack — version 4
webpack-cli — cliツール
webpack-node-externals — node-modules をサーバーサイドでbundleする。
npm install --save-dev webpack webpack-cli webpack-node-externals
为了将ES6+转译为ES5,需要安装Babel。
npm install --save-dev babel-core babel-loader babel-preset-env
要将index.html文件复制到dist目录中,需要安装html-loader和html-webpack-plugin。
npm install --save-dev html-loader html-webpack-plugin
需要创建一个Webpack配置文件 — webpack.config.js。
const path = require('path')
const webpack = require('webpack')
const nodeExternals = require('webpack-node-externals')
const HtmlWebPackPlugin = require("html-webpack-plugin")
module.exports = {
entry: {
server: './server.js',
},
output: {
path: path.join(__dirname, 'dist'),
publicPath: '/',
filename: '[name].js'
},
target: 'node',
node: {
// Need this when working with express, otherwise the build fails
__dirname: false, // if you don't put this is, __dirname
__filename: false, // and __filename return blank or /
},
externals: [nodeExternals()], // Need this to avoid error when working with Express
module: {
rules: [
{
// Transpiles ES6-8 into ES5
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
// Loads the javacript into html template provided.
// Entry point is set below in HtmlWebPackPlugin in Plugins
test: /\.html$/,
use: [{loader: "html-loader"}]
}
]
},
plugins: [
new HtmlWebPackPlugin({
template: "./index.html",
filename: "./index.html",
excludeChunks: [ 'server' ]
})
]
}
注意:
excludeChunks用于排除名为服务器的文件。这是一个Web文件,对于应用程序本身来说是不必要的,因此不希望将其包含在HTML文件中。
需要在server.js中设置ES6+的import语法来替代require,并测试Babel传输是否正常进行。
import path from 'path'
import express from 'express'
const app = express(),
DIST_DIR = __dirname,
HTML_FILE = path.join(DIST_DIR, 'index.html')
app.use(express.static(DIST_DIR))
app.get('*', (req, res) => {
res.sendFile(HTML_FILE)
})
const PORT = process.env.PORT || 8080
app.listen(PORT, () => {
console.log(`App listening to ${PORT}....`)
console.log('Press Ctrl+C to quit.')
})
请在您的根目录下创建一个名为.babelrc的文件,并使用以下代码输入。
{
'presets': ['env']
}
将package.json文件中的script字段修改为以下内容:
对于Unix系操作系统
"scripts": {
"build": "rm -rf dist && webpack --mode development",
"start": "node ./dist/server.js"
},
对于Windows操作系统而言,package.json文件中的代码段如下所示:
“scripts”: {
“build”: “(如果存在 dist 文件夹则删除 dist /s /q) && webpack –mode development”,
“start”: “node ./dist/server.js”
}Note: This is a translation to simplified Chinese.
通过这种方式,始终从新的 dist 文件夹开始,并通过命令行以声明性的方式设置开发模式。
你可以执行”npm run build”和”npm start”,然后导航到http://localhost:8080进行测试。
在这个阶段,应该没有错误。我正在逐步构建这个步骤,因为我正在写这篇文章。
步骤三:为应用程序添加CSS和Javascript的功能
尽管已经实现了相当多的功能,但您可以向应用程序中添加CSS样式、JavaScript和图片。
为了执行这个操作,需要将Webpack配置拆分成两个文件。之后会变为三个文件。
webpack.server.config.jsサーバーコードだけをバンドルする。
webpack.config.jsアプリケーションコードをバンドルする。
接下来,我们将把这个主要的设定文件分成开发版和生产版,并将服务器文件分成开发版和生产版。
首先,让我们安装所需的依赖关系。
npm install --save-dev css-loader file-loader style-loader
我们的目录结构如下
.babelrc
.git
.gitignore
README.md
dist
node_modules
package-lock.json
package.json
webpack.config.js
webpack.server.config.js
src
index.js
html
index.html
css
style.css
js
logger.js ※原文ではindex.jsだが誤り。
img
bg.jpg ※原文ではawful-selfie.jpgだが誤り。原文ではbg.jpgを置く手順が抜けている。
server
server.js
调整package.json文件中的脚本配置。
如果是Unix系操作系统
"scripts": {
"build": "rm -rf dist && webpack --mode development --config webpack.server.config.js && webpack --mode development",
"start": "node ./dist/server.js"
},
Windows操作系统下,
在package.json文件中的scripts字段中,有如下配置:
“build”: “(如果dist文件夹存在,则删除dist文件夹及其目录下的所有文件) && 使用webpack命令以开发模式执行webpack.server.config.js配置文件 && 使用webpack命令以开发模式执行”,
“start”: “运行node ./dist/server.js命令”。
请更新./src/html/index.html文件。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Express and Webpack App</title>
<link rel="shortcut icon" href="#">
</head>
<body>
<h1>Expack</h1>
<p class="description">Express and Webpack Boilerplate App</p>
<div class="awful-selfie"></div>
</body>
</html>
请更新 ./src/css/style.css 文件。
h1, h2, h3, h4, h5, p {
font-family: helvetica;
color: #3e3e3e;
}
.description {
font-size: 14px;
color: #9e9e9e;
}
.awful-selfie{
background: url(../img/bg.jpg);
width: 300px;
height: 300px;
background-size: 100% auto;
background-repeat: no-repeat;
}
更新 ./src/index.js 文件,检查导入和样式功能是否正常,确认基本功能。
import logMessage from './js/logger'
import './css/style.css'
// Log message to console
logMessage('Welcome to Expack!')
当然的啦。/src/js/logger.js
const logMessage = msg => console.log(msg)
export default logMessage
只需将server.js从根目录移动到./src/server。这将使根目录保持清洁,并将服务器代码保存在适当的位置。
最后,让我们配置Webpack。我们将从./webpack.server.config.js开始。
const path = require('path')
const webpack = require('webpack')
const nodeExternals = require('webpack-node-externals')
module.exports = {
entry: {
server: './src/server/server.js',
},
output: {
path: path.join(__dirname, 'dist'),
publicPath: '/',
filename: '[name].js'
},
target: 'node',
node: {
// Need this when working with express, otherwise the build fails
__dirname: false, // if you don't put this is, __dirname
__filename: false, // and __filename return blank or /
},
externals: [nodeExternals()], // Need this to avoid error when working with Express
module: {
rules: [
{
// Transpiles ES6-8 into ES5
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
}
]
}
}
然后,我们在./webpack.config.js中完成所有的工作。
const path = require("path")
const webpack = require('webpack')
const HtmlWebPackPlugin = require("html-webpack-plugin")
module.exports = {
entry: {
main: './src/index.js'
},
output: {
path: path.join(__dirname, 'dist'),
publicPath: '/',
filename: '[name].js'
},
target: 'web',
devtool: '#source-map',
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: "babel-loader",
},
{
// Loads the javacript into html template provided.
// Entry point is set below in HtmlWebPackPlugin in Plugins
test: /\.html$/,
use: [
{
loader: "html-loader",
//options: { minimize: true }
}
]
},
{
test: /\.css$/,
use: [ 'style-loader', 'css-loader' ]
},
{
test: /\.(png|svg|jpg|gif)$/,
use: ['file-loader']
}
]
},
plugins: [
new HtmlWebPackPlugin({
template: "./src/html/index.html",
filename: "./index.html",
excludeChunks: [ 'server' ]
})
]
}
请注意使用目标为’web’的app构建方法。这非常重要。请再次确认,如果使用目标为’node’会导致错误。
运行npm run build时,不会发生错误。
请点此继续阅读。本篇文章将介绍如何使用Webpack将Express捆绑打包。由于这是一篇在qrunch发表的文章,我稍后会将其上传到Qiita。