以前刚接触webpack的时候,我对它繁琐复杂的配置一个头两个大,后来项目渐渐做的多了,懂得多了,就渐渐熟悉了,而且也深深的理解了它的好处。
不管是做前端项目,还是用node做后端项目,只要和js相关的,都可以用webpack辅助构建,它可以提供es6语法的支持、开发热更新、部署代码压缩、对各种资源文件的处理……等等许多功能。
下面介绍在node框架koa开发的项目中,如何进行webpack配置。
一、新建koa项目
新建koa-demo
文件夹,通过npm初始化项目。然后创建以下目录结构、文件和内容:
项目目录
koa-demo
|- package.json
+ |- /src
+ |- index.js
src/index.js
// 先npm安装koa
// 这里引用和初始化
const Koa = require('koa')
const app = new Koa()
app.use(async ctx => {
ctx.body = 'hello koa'
})
// 监听端口
app.listen(3000)
这样一个简单的koa项目就创建好了。
二、配置webpack
接下来就是重点了,配置webpack,我们先安装相关所有需要的依赖,再解释为什么要这样配置:
注:这里所有配置以webpack4版本为基础,升级webpack5可去官方查看
npm i -D webpack@4 webpack-cli@3
# 安装webpack4版本
# 安装webpack-cli3版本 此工具用于在命令行中运行 webpack
npm i -D clean-webpack-plugin
# 常用插件,打包前自动清理之前打包的文件
npm i -D webpack-node-externals
# 打包时排除node_modules,里面的所有依赖都不打包
npm i -D @babel/core @babel/node @babel/preset-env babel-loader
# 使用es6语法所需的babel相关依赖
# @babel/node在babel7中被移了出来,如果在node环境中使用,要单独安装,有在运行Babel预设和插件之前进行编译的好处,调试用
npm i -D terser-webpack-plugin@4
# 生产环境需要打包压缩代码
npm i -D webpack-merge
# 分开发配置和生产配置,它们有共同配置,抽离出来,通过webpack-merge合并
npm i -D nodemon
# 监控node.js 源代码的变化和自动重启服务
npm i -D cross-env
# 运行跨平台设置和使用环境变量的脚本
npm i -D npm-run-all
# 实现同时执行多个命令
npm i -D rimraf
# 以包的形式包装rm -rf命令,用来删除文件和文件夹的。用来清理dist目录
我们的koa项目分为开发时环境和生产时环境,不同环境时webpack的配置是有部分不同的,所以要新建两个配置文件webpack.config.dev.js
和 webpack.config.prod.js
,同时它们又有共同之处,所以需要一个通用配置文件webpack.config.base.js
。
所以在项目根目录下新建config文件夹,把这三个webpack配置文件放进去。
项目目录
koa-demo
+ |- config
+ |- webpack.config.base.js
+ |- webpack.config.dev.js
+ |- webpack.config.prod.js
|- package.json
|- /src
|- index.js
接下来在通用配置文件webpack.config.base.js
中配置:
config/webpack.config.base.js
const path = require('path')
const webpack = require('webpack')
const nodeExternals = require('webpack-node-externals')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const webpackConfig = {
target: 'node', // koa项目仅在node环境下运行,因此设置称'node'
entry: {
// 设置入口文件
server: path.join(__dirname, '../src/index.js')
},
output: {
// 设置打包后的文件和位置
filename: '[name].bundle.js',
path: path.join(__dirname, '../dist')
},
// devtool: 'inline-source-map',
module: {
rules: [
{
test: /\.js|jsx$/,
use: {
loader: 'babel-loader'
},
// 尽量将 loader 应用于最少数量的必要模块,因此设置include
// 只针对该目录下的js文件进行babel处理
include: path.join(__dirname, '../src')
}
]
},
resolve: {
// modules: 告诉webpack哪些目录需要搜索去匹配解析
modules: [path.join(__dirname, '../src/index.js'), 'node_modules'],
// extensions: 告诉webpack这些后缀文件需要去搜索匹配
extensions: ['.js', '.json'],
alias: {
// 设置别名指向对应目录
'@': path.join(__dirname, '../src')
}
},
externals: [nodeExternals()], // 排除对node_modules里的依赖进行打包
plugins: [
new CleanWebpackPlugin(), // 打包前清除输出目录
new webpack.DefinePlugin({
// 定义环境变量,区分开发和生产环境
// 具体详情可查看DefinePlugin文档
'process.env.NODE_ENV':
process.env.NODE_ENV === 'production'
? JSON.stringify('production')
: JSON.stringify('development')
})
],
// node下这些选项可以使最初为Node.js环境编写的代码,在其他环境(如浏览器)中运行
node: {
console: true,
global: true,
process: true,
Buffer: true,
__filename: true,
__dirname: true,
setImmediate: true,
path: true
}
}
module.exports = webpackConfig
config/webpack.config.dev.js
const { merge } = require('webpack-merge')
const baseConfig = require('./webpack.config.base')
// 通过webpack-merge合并基础配置,添加开发时配置
const webpackConfig = merge(baseConfig, {
mode: 'development', // 开发模式
devtool: 'eval-source-map', // 开发时出错能知道在源代码中哪一行
stats: {
children: false, // webpack打包时子模块信息设置不显示
modules: false // 不显示模块信息
}
})
module.exports = webpackConfig
config/webpack.config.prod.js
const { merge } = require('webpack-merge')
const baseConfig = require('./webpack.config.base')
const TerserPlugin = require('terser-webpack-plugin')
// 通过webpack-merge合并基础配置,添加生产时配置
const webpackConfig = merge(baseConfig, {
mode: 'production', // 生产模式
stats: {
children: false, // webpack打包时子模块信息设置不显示
warnings: false // 警告不显示
},
optimization: {
minimizer: [
// terser-webpack-plugin插件可以压缩代码
// 在webpack4版本中需要安装terser-webpack-plugin4版本
// 里面是官方推荐的具体的参数,详情可查看文档
new TerserPlugin({
terserOptions: {
warning: true,
compress: {
warnings: false,
drop_console: false, // 取消注释console 方便有时候进行调试
dead_code: true,
drop_debugger: true
},
output: {
comments: false, // 不要注释
beautify: false // 不要格式,一行显示所有代码
},
mangle: true
},
parallel: true, // 使用多进程并行运行可提高构建速度,默认的并发运行数量 os.cpus().length - 1
sourceMap: false
})
],
// splitChunks 用来避免模块之间重复的依赖关系
splitChunks: {
cacheGroups: {
commons: {
name: 'commons',
chunks: 'initial',
minChunks: 3,
enforce: true
}
}
}
}
})
module.exports = webpackConfig
1、配置babel去支持es6语法
接着在根目录下新建.babelrc
文件,增加babel配置:
{
"presets": [
[
"@babel/preset-env",
{
"targets": {
"node": "current"
}
}
]
]
}
改写src/index.js中的代码:
- const Koa = require('koa')
+ import Koa from 'koa'
const app = new Koa()
app.use(async ctx => {
ctx.body = 'hello koa'
})
// 监听端口
app.listen(3000)
如果我们用node src/index.js
去运行,则会报错:
import Koa from 'koa'
^^^^^^
SyntaxError: Cannot use import statement outside a module
在在安装babel之后,node_modules中提供了一个babel-node
命令,我们可以通过该命令来运行我们的入口文件。
npx babel-node src/index.js
配合之前安装的nodemon
可以实现热更新
npx nodemon --exec babel-node src/index.js
我们在package.json
中添加这个脚本:
{
"script": {
"start": "nodemon --exec babel-node src/index.js"
}
}
这样通过在终端里运行npm run start
即可启动项目了。
当然这个只是简单的实现去支持es6语法和开发时热更新功能,并没有通过用webpack去构建,在项目简单的情况下尚可。后面将介绍通过webpack去启动。
2、调试webpack配置文件
运行命令去监听webpack配置文件:
npx node --inspect-brk ./node_modules/.bin/webpack --config config/webpack.config.prod.js --progress
# --config 指定要监听的配置文件
# --progress 打印webpack编译的过程
可以在chrome浏览器里调试,也可以在编辑器里调试,具体方法见node调试文档。
我们在package.json
中添加这个脚本用来调试用:
{
"script": {
"start": "nodemon --exec babel-node src/index.js",
"webpack:debug": "node --inspect-brk ./node_modules/.bin/webpack --config config/webpack.config.prod.js --progress"
}
}
3、通过webpack构建开发时环境
我们已经把开发时环境配置好了,接下来就是启动它,通过webpack --watch
命令来监听项目中文件的变化,如果其中一个文件被更新,代码将被重新编译,而不必再去手动运行整个构建。
同时我们通过cross-env
来设置环境变量,来指定当当前开发环境还是生产环境。
npx cross-env NODE_ENV=development webpack --watch --config config/webpack.config.dev.js --progress
执行该命令的意思就是,设置一个环境变量NODE_ENV,值为development,因为我们之前在配置文件中通过DefinePlugin做了配置,所以当这个值不是production时就是开发环境,定义了对应的变量,在项目文件中就可以拿到这个变量,来针对开发和生产时做不同的逻辑处理。
设置了开发时的环境变量后,通过webpack --watch
启动监听模式,指定开发时的配置文件config/webpack.config.dev.js
文件,当项目中文件发生变化,代码将被重新编译打包输出到dist/server.bundle.js
。
但仅仅这样时不够的,文件虽然重新被编译并打包了,但是我们并没有监听这个打包后的文件,因此我们通过nodemon
来监听输出后的文件:
npx nodemon --inspect ./dist/server.bundle.js
我们这时候将不再简单的监听原始入口文件src/index.js
了,而是监听经过了webpack处理(包括babel转换、代码压缩等)打包后生成的文件。
通过运行上面这两个命令就可以帮助我们实现构建开发时环境。我们把该命令配置到package.json
脚本中:
{
"script": {
"start": "nodemon --exec babel-node src/index.js",
"webpack:debug": "node --inspect-brk ./node_modules/.bin/webpack --config config/webpack.config.prod.js --progress",
"watch": "cross-env NODE_ENV=development webpack --watch --config config/webpack.config.dev.js --progress",
"debug": "nodemon --inspect dist/server.bundle.js"
}
}
但是这是两个命令,一个终端控制台只能监听一个命令,如果每次启动项目都开两个终端比较麻烦,所以我们安装一个工具npm-run-all
,来实现一个脚本同时执行多个命令。继续在package.json
中添加脚本:
{
"script": {
"start": "nodemon --exec babel-node src/index.js",
"webpack:debug": "node --inspect-brk ./node_modules/.bin/webpack --config config/webpack.config.prod.js --progress",
"watch": "cross-env NODE_ENV=development webpack --watch --config config/webpack.config.dev.js --progress",
"debug": "nodemon --inspect dist/server.bundle.js",
"start:dist": "npm-run-all -p watch debug"
}
}
npm-run-all -p watch debug
命令的含义是并行执行watch和debug两个脚本命令-p
是并行执行的意思。
配置好后,我们直接在终端运行即可启动开发时环境了:
npm run start:dist
然后就可以安心写koa项目代码啦。
4、项目打包,运用到生产环境
项目写好之后,我们需要打包部署到线上生产环境,这时候再通过npm run start:dist
命令就不合适了,因此我们来配置下构建生产环境的打包命令。
npx cross-env NODE_ENV=production webpack --config config/webpack.config.prod.js
和上面构建开发环境的命令很类似,不过此时我们设置环境变量NODE_ENV值为production,并指定配置文件config/webpack.config.prod.js
文件去打包构建。
我们把该命令配置到package.json
中:
{
"script": {
"start": "nodemon --exec babel-node src/index.js",
"webpack:debug": "node --inspect-brk ./node_modules/.bin/webpack --config config/webpack.config.prod.js --progress",
"watch": "cross-env NODE_ENV=development webpack --watch --config config/webpack.config.dev.js --progress",
"debug": "nodemon --inspect dist/server.bundle.js",
"start:dist": "npm-run-all -p watch debug",
"build": "cross-env NODE_ENV=production webpack --config config/webpack.config.prod.js"
}
}
运行该命令:
npm run build
即完成了生产环境下的项目打包构建。
将整个项目目录除了node_modules
文件夹,推送到线上服务器,然后运行npm install
安装依赖,接着用node命令执行文件node dist/server.bundle.js
把项目启动起来,通过服务器地址和暴露的端口既可以访问koa项目接口啦。
三、配置eslint + prettier风格
我习惯写项目必配eslint,操作如下:
1、安装eslint
# 安装eslint
npm i eslint -D
# eslint初始化
npx eslint --init
# 进入自定义选择项
# 1. 你想要怎么使用eslint? To check syntax and find problems
# 2. 哪一种模块是你的项目使用的? JavaScript modules
# 3. 选择哪一个框架? None of these
# 4. 你想要使用TypeScript吗? N
# 5. 你要运行在哪个环境? Browser, Node
# 6. 你想要配置文件格式是哪个? JavaScript
# 全部选择完成后,会在本地生成.eslintrc.js文件
2、安装prettier
# 安装相关配置依赖
npm install --save-dev eslint-config-prettier
npm install --save-dev eslint-plugin-prettier
npm install --save-dev --save-exact prettier
然后在.eslintrc.js
文件中添加配置:
module.exports = {
...
plugins: ['prettier'],
extends: ['eslint:recommended', 'prettier', 'prettier/prettier'],
rules: {
'prettier/prettier': 'error'
}
}
具体的prettier规则可以新建一个.prettierrc
文件设置。
{
"semi": false, // 结尾是否加分号
"singleQuote": true, // 是否使用单引号
"printWidth": 80, // 一行代码最长显示80的length
"endOfLine": "auto",
"trailingComma": "none" // 对象或者数组结尾一项是否逗号
}
另外为了增加验证效率,排除那些不需要验证规则的文件,比如mode_modules
,可以新建.eslintignore
和.prettierignore
文件。
四、提交git前代码检查
为了增强代码线上质量,可以在git提交到仓库前使用husky
和lint-staged
进行检查。
它们的功能就是在git提交时触发钩子,其中最重要的一个钩子是pre-commit
,在提交代码前可以让我们配置具体做什么,比如运行一下代码检查,如果不符合eslint规则的就中止这次git提交,让你去检查代码问题。
配置它们很简单,先安装这两个工具。
npm install husky lint-staged --save-dev
然后在package.json
中增加配置:
{
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"lint-staged": {
// 匹配所有js文件,按顺序执行任务
"*.js": [
"prettier --write",
"eslint",
"git add"
]
}
}
git的hooks可以在.git文件下的hooks目录里去查看它们,我们可以理解为执行git操作过程中的一系列生命周期,就像vue生命周期一样,在提交时触发一个pre-commit
钩子,里面可以执行提交前要做的事情。比如可以执行检查代码:
{
"husky": {
"hooks": {
"pre-commit": "prettier --write"
}
}
}
这样它就在提交前执行了prettier修复命令。但是这样有一个问题,就是它会检查项目所有的代码,而不是仅仅你这次提交的,所以我们需要lint-staged
来解决这个问题,而且lint-staged
中可以分任务去执行多个命令。
{
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"lint-staged": {
// 匹配提交的所有js文件,按顺序执行任务
"*.js": [
"prettier --write",
"eslint",
"git add"
],
// 匹配提交的所有vue文件,按顺序执行任务
"*.vue": [...]
}
}
上述检查js文件的任务就是,先通过prettier --write *.js
命令修复文件中不符合规则的代码,执行完后再执行eslint *.js
命令检查不符合eslint规则的代码,没问题后执行git add *.js
将修复的文件(如果有修复更改)重新添加到暂存区,然后再执行提交操作。
这其中有任何一个任务没通过,则本地提交中止,显示报错信息,提醒你规范代码。
通过以上所有基础配置,开发koa项目之前的构建环境已经搭建完成,接下来只需要安心写项目代码即可。
后续可针对这些配置,再加上koa系列相关基础中间件,做成脚手架,以减少重复搭建项目基础环境的成本。
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!