搭配Npm Script
认识Npm Script
是一个任务执行者,Npm是安装node时候附带的包管理器,Npm Script是Npm的内置功能,允许再package.json中使用scripts字段定义任务
{
"scripts": {
"dev": "node dev.js",
"build": "node build.js"
}
}
执行npm run dev相当于执行node dev.js命令
它还可以运行安装到node_modules里的可执行模块,如有模块npm i -D webpack,我们可以:
{
"scripts": {
"dev": "webpack"
}
}
为啥webpack需要Npm Script
webpack只是一个模块化打包工具,没有提供任何管理功能 举个栗子: 要求:
- 开发阶段,需要DevServer,并且需要输出Source Map方便调试
- 减少发布到线上的代码尺寸,构建时压缩输出的代码
- 在构建完发布到线上的代码后,需要将构建的代码提交给发布系统
1,2冲突,3依赖2,所以可以定义三个不同的任务
{
"scripts": {
"dev": "webpack-dev-server --open",
"dist": "NODE_ENV=production webpack --config webpack_dist.config.js",
"pub": "npm run dist && rsync dist"
}
}
- dev:开发时执行的任务,通过DevServer启动构建
- dist:构建出发布到线上的代码
- pub:先构建出发布到线上的代码,再同步dist目录中的文件到发布系统
检查代码
主要检查什么
- 代码风格
- 潜在问题
怎么检查
检查js
最常见的工具ESlint,npm i -g eslint安装到全局后,执行eslint init来新建一个ESlint配置文件.eslintrc,文件格式为JSON,如果想覆盖默认检查规则,或者想加入新的检查规则,则需要修改该文件,例如
{
// 从eslint:recommended中继承所有检查规则
"extends": "eslint:recommended",
// 再自定义一些规则
"rules": {
// 需要在每行结尾加
"semi": ["error", "always"],
// 需要使用“”包裹字符串
"quotes": ["error", "double"]
}
}
写好配置文件后再执行eslint 文件名.js检查这个文件
检查ts
TSlint,和ESlint相似,但是TSlint只检查ts代码
npm i -g tslint
tslint --init
tslint 文件名.js
检查CSS
stylelint,给予postcss,能检查任何postcss能解析的代码,scss,less 1、npm i -g stylelint 2、项目根目录新建.stylelintrc配置文件,JSON格式,和eslint配置相似,如
{
// 继承stylelint-config-standard中所有的检查规则
"extends": "stylelint-config-standard",
// 自定义检查
"rules": {
"at-rule-empty-line-before": null
}
}
3、执行stylelint "文件名.css"
结合Webpack检查代码
结合ESlint
eslint-loader:
module.exports = {
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'eslint-loader',
// 将eslint-loader执行顺序放到最前面,防止其他Loader将处理后的代码交给eslint-loader去检查
enforce: 'pre'
}
]
}
}
结合TSlint
module.exports = {
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'tslint-loader',
// tslint-loader执行顺序放到最前面,防止其他Loader将处理后的代码交给tslint-loader去检查
enforce: 'pre'
}
]
}
}
结合stylelint
StyleLintPlugin
const StyleLintPlugin = require('stylelint-webpack-plugin');
module.exports = {
// ...
plugins: [
new StyleLintPlugin(),
]
}
将代码检查功能加到webpack中会导致以下问题 1、执行检查的计算量大,所以构建速度变慢 2、输出的错误信息通过行号定位,没有编辑器集成显示错误直观 解决方案: 1、使用继承了代码检查的编辑器,可以实时直观的显示错误 2、将代码检查步骤放到代码提交时,只有检查通过时才提交代码
husky可以方便快速为项目接入Git Hook,执行
npm i -D husky会通过Npm Script Hook自动配置好Git Hook,我们需要做的是在package.json中定义几个脚本
{
"scripts": {
// 在执行git commot前会执行的脚本
"precommit": "npm run lint",
// 在执行git push时会执行的脚本
"prepush": 'lint,
// 调用eslint,stylelint等工具检查代码
"lint": "eslint && stylelint"
}
}
通过Node.js API启动Webpack
Webpack除了提供了可执行的命令行工具,还提供了可在Node.js环境中调用的库,通过Webpack暴露出的API,可直接再Node.js程序中调用Webpack执行构建 通过API去调用并执行Webpack,比直接通过可执行文件启动灵活
安装和使用Webpack模块
1、调用Webpack API前,需要先安装它,npm i -D webpack
2、导入Webpack模块
const webpack = require('webpack');
// es6语法
import webpack from "webpack";
// 导出的webpack其实是一个函数,使用方法
webpack({
// Webpack配置,和webpack.config.js文件一致
}, (err, stats) => {
if(err || stats.hasErrors()) {
// 构建过程出错
}
// 成功执行完构建
})
如果我们将Webpack配置写在webpack.config.js文件中,如下:
// 读取webpack.config.js文件中的配置
const config = require('./webpack.config.js');
webpack(config, callback);
以监听模式运行
以上使用Webpack API的方法只能执行一次构建,无法以监听模式启动webpack,所以我们要获取Compiler实例以使用API时启动监听模式(关于watchOptions参考)
const compiler = webpack(config);
// 调用compiler.watch并以监听模式启动,返回的watching用于关闭监听
const watching = compiler.watch({
// watchOptions
aggregateTimeout: 300,
}, (err, stats) => {
// 每次因文件发生变化而重新执行完构建后
});
// 调用watching.close关闭监听
watching.close(() => {
// 关闭监听后
})
使用Webpack Dev Middleware
DevServer是一个方便开发的小型HTTP服务,DevServer是基于webpack-dev-middleware和Exressjs实现的,webpack-dev-middleware是Expressjs的一个中间件 看看实现DevServer的大致代码:
const express = require('express');
const webpack = require('webpack');
const webpackMilleware = require('webpack-dev-middleware');
// 从webpack.config.js文件中读取webpack配置
const config = require('./webpack.config.js');
// 实例化一个Expressjs app
const app = express();
// 读取到的webpack配置实例化
const compiler = webpack(config);
// 为app注册webpackMiddleware中间件
app.use(webpackMiddleware(compiler));
// 启动HTTP服务器,服务器监听在3000端口
app.listen(3000)
webpackMiddleware函数返回结果是Expressjs中间件,有以下功能
- 接收来自webpack compiler实例输出的文件,但是不会将文件输出到磁盘,而是保存在内存中
- Expressjs app上注册路由,拦截HTTP收到的请求,根据请求路径相应对应的文件内容
Webpack Dev Middleware支持的配置项
Node调用webpac-dev-milldeware提供的api时,可以向它传入一些配置项,方法如下:
// webpackMilddleware函数的第二个参数为配置项
app.use(webpackMiddleware(compiler, {
// 在webpack-dev-middleware支持的所有配置项中,只有publicPath属性为必填项,其他都是选填
// webpack输出资源绑定HTTP服务器根目录,和webpack配置中的publicPath含义一致
pubilcPath: '/assets/',
// 不输出info类型的日志到控制台,只输出warn和error类型的日志
noInfo: false,
// 不输出任何类型的日志到控制台
quiet: false,
// 切换到懒惰模式,这意味着不监听文件的变化,只会再有请求时再编译对应的文件,适合页面非常多的项目
lazy: true,
// watchOptions
// 只在非懒惰模式下才有用
watchOptions: {
aggregateTimeout: 300,
poll: true
},
// 默认的URL路径,默认时index.html
index: 'index.html',
// 自定义HTTP头
headers: {
'X-Custom-Header': 'yes'
},
// 为特定后缀文件添加HTTP mimeTypes作为文件类型映射表
mimiTypes: {
'text/html': ['phtml']
},
// 统计信息输出样式
stats: {
colors: true
},
// 自定义输出日志的展示方法
reporter: null,
// 开启或关闭服务器渲染
serverSideRender: false,
}))
Webpack Dev Middleware与模块热替换
DevServer提供了模块热替换功能,虽然它基于webpack-dev-middleware实现,但是webpack-dev-middleware并没有实现模块热替换功能,DevServer自己实现了该功能 怎么滴才能在使用webpack-dev-middleware时候也能使用模块热替换呢? 1、修改webpack.config.js,加入HotModuleReplacementPlugin:
const HtoModuleReplacementPlugin = require('webpack/HotModuleReplacementPlugin');
module.exports = {
entry: [
// 为了支持模块热替换,注入代理客户端
'webpack-hot-middleware/client',
// JS执行入口文件
'./src/main.js'
],
output: {
// 将所有依赖的模块合并输出到一个bundle.js文件
filename: 'bundle.js',
},
plugins: [
// 为了支持模块热替换,生成.hot-update.json文件
new HotModuleReplacementPlugin(),
]
devtool: 'source-map',
}
相当于完成webpck-dev-server --hot工作 2、修改HTTP服务器代码的server.js文件,接入webpack-hot-middleware中间件,修改如下:
const express = require('express');
const webpack = require('webpack');
const webpackMiddleware = require('webpack-dev-middleware');
// 从webpack.config.js文件中读取webpack配置
const config = require('./webpack.config.js');
// 实例化一个Expressjs app
const app = express();
// 用读取到的Webpack配置实例化一个Compiler
const compiler = webpack(config);
// 为app注册webpackMiddleware 中间件
app.use (webpackMiddleware(compiler));
// 为了支持模块热替换,响应用于替换老模块的资源
pp.use(require('webpack-hot-middleware')(compiler));
// 将项目根目录作为静态资源目录,用于服务HTML文件
app.use (express.static('.'));
// 启HTTP服务器,服务器监听在3000端口
app.listen(3000, () => {
console.info('成功监听 3000');
}
3、修改执行入口文件main.js,加入替换逻辑,在文件末尾加入以下代码:
if(module.hot) {
module.hot.accept()
}
4、安装依赖
npm i -D webpack-dev-middleware webpack-hot-middleware express
安装成功后,通过
node ./server.js就能启动一个类似于Dev Server 的支持模块热替换的自定义HTTP服务。