内容简介:webpack 作为目前主流的构建工具,其较快的版本迭代和复杂的配置方式,使得每次开发前不得不规划相当部分时间来调试。这里将记录整个环境的搭建过程,为新手提供基础思路。就像我在开发以上三个作为开发一个组件(
webpack 作为目前主流的构建工具,其较快的版本迭代和复杂的配置方式,使得每次开发前不得不规划相当部分时间来调试。这里将记录整个环境的搭建过程,为新手提供基础思路。
就像我在开发 vue-sitemap
时一样,构建 工具 往往需要达到下面几个需求:
- 构建生成 CommonJS/UMD/ES Modules 三种模式的代码提供给使用者
- 需运行测试和检查测试覆盖的进度
- 开发时候使用VS Code 编辑器进行断点调试
以上三个作为开发一个组件( package
)是基础中基础的需求,当然还有更多细节内容需要添加,由于篇幅过长另加文章再说吧。(欢迎各位读者评论留下你认为需要的功能( • ̀ω•́ )✧)
第一步:构建工具
接下来我们先从最基础的开始,需要安装Node.js(10.x) 作为所有代码的运行环境, webpack 也是一样。
初始化项目
由于我需要把项目发布至 npm 的,使用命令初始化项目描述文件 package.json
npm init 复制代码
初次化细节各位读者找其他文章补全吧,这里不细说
接下来看看目录结构
│ package.json //项目描述文件 │ README.md //GitHub创建仓库时默认创建 ├─src //源代码目录 │ index.js //入口文件 ├─tests //测试代码目录 │ ├─dist //生产文件的目录 │ └─docs //文档目录 复制代码
添加 webpack
npm install -D webpack webpack-cli cross-env //or //yarn add webpack webpack-cli cross-env -D 复制代码
这里使用的 webpack v4,后续设置也是基于4来设置, cross-env
是帮助在 win 下能正常使用环境变量的包,我开发在 win 环境于是在这加上。
yarn 是一款快速、可靠、安全的依赖管理工具。如果你觉得 npm 安装时候较慢的话,不妨试试。
等依赖下载解决完毕之后,,在 package.json
设置构建命令方便之后使用。
//# package.json { //... "scripts": { "build": "cross-env NODE_ENV=production webpack --propress --hide-modules", } } 复制代码
这里我们可以尝试运行一下命令 npm run build
尝试能否构建成功,成功的情况下在 dist
目录下会生成 main.js
的文件。
配置 webpack
创建 webpack.config.js
文件来配置 webpack 。为满足我们的第一个需要生成三种模式的代码:
//# webpack.config.js const package = require('./package.json') const path = require('path') const config = { entry: "./src/index.js", //入口文件 output: { //输出设置 path: path.resolve(__dirname, "./dist"), filename: `${package.name}.js` }, resolve: { alias: { "@": path.resolve(__dirname, "./src") } } } if (process.env.NODE_ENV === "umd") { config.optimization = { minimize: false }; config.output.library = package.name; config.output.libraryTarget = "umd2"; config.output.filename = `${package.name}.js`; } if (process.env.NODE_ENV === "umd:min") { config.output.library = package.name; config.output.libraryTarget = 'umd2'; config.output.filename = `${package.name}.min.js`; } if (process.env.NODE_ENV === "es") { config.output.library = package.name; config.output.libraryTarget = "amd"; config.output.filename = `${package.name}.es.js`; } if (process.env.NODE_ENV === "commonjs") { config.output.library = package.name; config.output.libraryTarget = "commonjs2"; config.output.filename = `${package.name}.common.js`; } module.exports = config 复制代码
添加构建命令
为 package.json
添加新的运行命令
//# package.json { "version": "0.1.0", "name": "vscode-mocha-webpack-example", "description": "用于管理导航、面包屑及路由等基于vue的功能整合", "main": "./src/index.js", "scripts": { "build": "npm run build:commonjs && npm run build:es && npm run build:umd && npm run build:umd:min", "build:umd": "cross-env NODE_ENV=umd webpack --mode=production --progress --hide-modules", "build:umd:min": "cross-env NODE_ENV=umd:min webpack --mode=production --progress --hide-modules", "build:es": "cross-env NODE_ENV=es webpack --mode=production --progress --hide-modules", "build:commonjs": "cross-env NODE_ENV=commonjs webpack --mode=production --progress --hide-modules" } ... } 复制代码
运行 npm run build
就会 CommonJS/UMD/ES Modules 三种模式生成对应的文件。
大概是这样子:
├─dist │ vscode-mocha-webpack-example.common.js │ vscode-mocha-webpack-example.es.js │ vscode-mocha-webpack-example.min.js │ vscode-mocha-webpack-example.js 复制代码
指定终端
为了使你的构建文件成为最终发布包的一部分,你必须声明它们。将以下内容添加到package.json:
"main": "dist/vscode-mocha-webpack-example.common.js", "module": "dist/vscode-mocha-webpack-example.es.js", "jsnext:main": "dist/vscode-mocha-webpack-example.es.js", "files": [ "dist", "src" ], 复制代码
-
files
部分告诉npm在发布时打包这些文件夹(否则,它们将被忽略,因为它们列在.gitignore
文件中) -
main
定义CommonJS构建的终端 -
jsnext:main
和module
定义了ES2015构建的终端(我们定义了两个终端,因为jsnext:main
是最早使用的规范,而module
则更符合标准规范)。
第二步,设置babel
通过 babel
使得我们使用最新的语法,而不必担心运行环境不支持的问题。在 webpack
的下我们需要用到 babel-loader
来导入 babel
支持,关于最新的兼容设置还需使用上 babel-preset-env
:
npm install -D babel babel-cli babel-preset-env //or //yarn add babel babel-cli babel-preset-env -D 复制代码
创建 babel 配置文件
接着在 .babelrc
文件里设置babel兼容的规则:
{ "presets": [ [ "env", { "useBuiltIns": false, "modules": false } ] ] } 复制代码
为 webpack 添加 babel-loader
当我们使用最新语法编写 JavaScript 时,webpack 会匹配将所有 JS 文件给 babel
的处理。
const package = require('./package.json') const path = require('path') const config = { entry: "./src/index.js", output: { path: path.resolve(__dirname, "./dist"), filename: `${package.name}.js` }, resolve: { alias: { "@": path.resolve(__dirname, "./src") } }, module: { rules: [ { test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/ } ] } } ... module.exports = config 复制代码
当运行构建时 webpack
便会加载 babel
及其相关的设置将代码转换并生成,到这步构建相关的设置基本完成。
第三步,添加自动化测试
相信对自动化测试有所了解的读者应该对 mocha
并不陌生,不了解的可以先去补补相关知识再往下看。简单的测试较多使用 mocha
来进行处理,还有断言库 chai
和提供promise支持的 chai-as-promised
等等,下面先把这些依赖安装上:
npm install -D mocha mocha-webpack chai chai-as-promised //or //yarn add mocha mocha-webpack chai chai-as-promised -D 复制代码
测试代码想使用es新特性时可以使用 mocha-webpack
这个插件。
然后在 package.json
添加上测试命令:
{ //... "scripts": { "build": "npm run build:commonjs && npm run build:es && npm run build:umd && npm run build:umd:min", "build:umd": "cross-env NODE_ENV=umd webpack --mode=production --progress --hide-modules", "build:umd:min": "cross-env NODE_ENV=umd:min webpack --mode=production --progress --hide-modules", "build:es": "cross-env NODE_ENV=es webpack --mode=production --progress --hide-modules", "test": "cross-env NODE_ENV=test mocha-webpack tests/**/*.spec.js" } //... } 复制代码
.babelrc
也需要设置一下:
{ //... "env": { "test": { "presets": [ [ "env", { "modules": false, "targets": { "node": "current" } } ] ] } } } 复制代码
为了能测试添加 tests/unit/example.spec.js
和 src/index.js
两个文件,代码如下:
├─src │ index.js └─tests └─unit example.spec.js 复制代码
//# src/index.js export function getRole(user){ switch(user){ case "Packy": return "admin" case "Joan": return "reader" } } //# tests/unit/example.spec.js import { assert } from "chai"; import { getRole } from "@/index"; describe('Testing', ()=>{ it('Packy is admin', () => { assert.equal(getRole('Packy'), 'admin') }) it("Joan is reader", () => { assert.equal(getRole("Joan"), "reader") }); }) 复制代码
现在运行测试命令就能得出测试结果了:
npm run test 复制代码
大概输出是这个样子:
WEBPACK Compiling... [======================= ] 91% (additional chunk assets processing) WEBPACK Compiled successfully in 5893ms MOCHA Testing... Testing √ Packy is admin √ Joan is reader 2 passing (39ms) MOCHA Tests completed successfully 复制代码
关于测试覆盖率的问题
有了测试还得知道测试是否都覆盖了所有代码(听说基本要到80%,有些团队可能要求更高90~95%),那如何得知?
nyc
这个包就能帮助到我去检验测试覆盖率,首先先安装依赖:
npm install -D nyc babel-plugin-istanbul 复制代码
再设置检查范围和添加命令:
//# package.json { ... "scripts": { "build": "npm run build:commonjs && npm run build:es && npm run build:umd && npm run build:umd:min", "build:umd": "cross-env NODE_ENV=umd webpack --mode=production --progress --hide-modules", "build:umd:min": "cross-env NODE_ENV=umd:min webpack --mode=production --progress --hide-modules", "build:es": "cross-env NODE_ENV=es webpack --mode=production --progress --hide-modules", "build:commonjs": "cross-env NODE_ENV=commonjs webpack --mode=production --progress --hide-modules", "test": "cross-env NODE_ENV=test nyc mocha-webpack tests/**/*.spec.js" }, ... "nyc": { "include": [ "src/**" ], "instrument": false, "sourceMap": false } ... } 复制代码
安装依赖中也看到 babel
也需要添加相关的设置:
//# .babelrc { ... "env": { "test": { "presets": [ [ "env", { "modules": false, "targets": { "node": "current" } } ] ], "plugins": [ "istanbul" ] } } } 复制代码
运行 npm run test
将会得到以下内容:
WEBPACK Compiling... [======================= ] 91% (additional chunk assets processing) WEBPACK Compiled successfully in 5893ms MOCHA Testing... Testing √ Packy is admin √ Joan is reader 2 passing (39ms) MOCHA Tests completed successfully ----------|----------|----------|----------|----------|-------------------| File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s | ----------|----------|----------|----------|----------|-------------------| All files | 100 | 100 | 100 | 100 | | index.js | 100 | 100 | 100 | 100 | | ----------|----------|----------|----------|----------|-------------------| 复制代码
简单说一下这四栏东西代表什么意思:
Statement coverage Branch coverage Function coverage Line coverage
不在覆盖范围内的代码的行数会在 Uncovered Line
这栏显示。
为测试提供async/await支持
在测试中想使用async/await语法,需新增setup.js文件并在入口处添加 babel-polyfill
:
require("babel-polyfill"); 复制代码
并在 .babelrc
修改 useBuiltIns
为 entry
:
{ ... "env": { "test": { "presets": [ [ "env", { "useBuiltIns": "entry", "modules": false, "targets": { "node": "current" } } ] ], "plugins": [ "istanbul" ] } } } 复制代码
接下来在 src/index.js
和 tests/example.spec.js
两个文件添加新的代码:
//# src/index.js export function getUsers(){ return new Promise((resolve, reject)=>{ setTimeout(()=>{ console.log('123') resolve(['Packy', 'Joan']) }, 1000) }) } //# tests/unit/example.spec.js describe('GetUsers', ()=>{ it('get result is Array', async ()=>{ const users = await getUsers(); assert.isArray(users, "[message]"); }) }) 复制代码
运行测试就能看到效果!
让测试更进一步,在 VS Code 中调试
想在VS Code断点调试代码需要额外增加一些设置,添加以下代码至 webpack.config.js
。
//# webpack.config.js //... if (process.env.NODE_ENV === "test") { config.devtool = "eval-source-map"; config.output = Object.assign(config.output, { devtoolModuleFilenameTemplate: "[absolute-resource-path]", devtoolFallbackModuleFilenameTemplate: '[absolute-resource-path]?[hash]' }); } module.exports = config; 复制代码
在VS Code 添加调试代码
打开 VS Code 调试面板在下拉选项中选择添加配置(或者直接创建并打开 .vscode/launch.json
文件):
// 使用 IntelliSense 了解相关属性。 // 悬停以查看现有属性的描述。 // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 { "version": "0.2.0", "configurations": [ { "type": "node", "request": "launch", "name": "Mocha-webpack Tests", "program": "${workspaceFolder}/node_modules/mocha-webpack/bin/mocha-webpack", "args": [ "--full-trace", "--timeout", "999999", "--colors", "tests/**/*.js" ], "sourceMaps": true, "env": { "NODE_ENV": "test" }, "internalConsoleOptions": "openOnSessionStart" }] } 复制代码
在 src
目录下的源代码或是 tests
目录下的测试代码都能获得断点效果,想马上尝试可以下载本文例子 vscode-mocha-webpack-example
,安装依赖后就能尝试断点调试了。
设置参考源自 vscode-ts-webpack-node-debug-example
值得一提的是,上面参考例子原文说 devtool
使用 eval
相关的设置并不能断点,但是在使用 mocha-webpack
调试时上面例子并不能实现断点。在我和公司小伙伴多番寻找 vscode
和 mocha-webpack
的issue后,经过各种尝试下发现设置成 eval-source-map
便能实现最佳断点效果(eval也能实现但是由于断点sourcemap指向的源是生成后的文件导致在断点时多少会产生偏移)。
吐槽:在使用 nvm
切换 nodejs
环境时发现 npm
下载不了,打开github的下载链接直接404了,惊悚地发现 npm
整个搬走 (`Д´*)9 ┴┴,为解决这个问题请下载最新版本 v1.1.7
的 nvm
。
最后:
我的动力来自你的指头,请用你的指头使劲给我个赞吧!d(´ω` )
觉得本文有帮助的话不要忘记点一下收藏φ(>ω<*) 哦!
同时欢迎各路新手、大神在本文下方吐槽留言,谢谢参与讨论的各位仁兄!( • ̀ω•́ )✧
下面是本文完整例子,记得star一下!
同时非常感谢 Mather 协同编辑!
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
高性能JavaScript
Nicholas C.Zakas / 丁琛、赵泽欣 / 电子工业出版社 / 2010-11 / 49.00元
如果你使用JavaScript构建交互丰富的Web应用,那么JavaScript代码可能是造成你的Web应用速度变慢的主要原因。《高性能JavaScript》揭示的技术和策略能帮助你在开发过程中消除性能瓶颈。你将会了解如何提升各方面的性能,包括代码的加载、运行、DOM交互、页面生存周期等。雅虎的前端工程师Nicholas C. Zakas和其他五位JavaScript专家介绍了页面代码加载的最佳方......一起来看看 《高性能JavaScript》 这本书的介绍吧!