当前位置: 首页 > news >正文

vscode中安装webpack_GitHub - lpreterite/vscode-mocha-webpack-example: 用webpack写个现代的JavaScript包...

用webpack写个现代的JavaScript包

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 | |

----------|----------|----------|----------|----------|-------------------|

简单说一下这四栏东西代表什么意思:

Stmts : Statement coverage 声明覆盖率,程序中的每个语句都已执行吗?

Branch: Branch coverage 分支覆盖率,是否已执行每个控制结构的每个分支(也称为DD路径)(例如if和case语句)?例如,给定if语句,是否已执行true和false分支?

Funcs: Function coverage 方法覆盖率,是否已调用程序中的每个函数(或子例程)?

Lines: 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,安装依赖后就能尝试断点调试了。

值得一提的是,上面参考例子原文说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协同编辑!

相关文章:

  • c语言课设代写一般多少钱_cs代写 math代写
  • vs2019 值可能为0_【完整版】针对零基础小白的VS2019安装攻略
  • bin和cue怎么合并_用foobar进行APE分割及合并,cue的制作
  • vsftp如何确定地址_西门子S71500数字量输入模块如何编址?
  • adsense 注册_三天google AdSense帐户申请经验分享
  • plc和pc串口通讯接线_基础教程--RS232通讯用到串口调试软件的应用
  • host ntrip 千寻rtk_合众思壮新品RTK UFO U5连接千寻cors账号的方法教程
  • ipad鼠标圆圈变成箭头_iPad当作Mac mini 的显示器的方法
  • mc有什么红石机器人_Minecraft游戏理论:远古“巨石阵”之谜,探索mc史前高科技文明...
  • 整活插件 炉石传说_炉石传说:整活被盯上了,卡德加可能被移除,拔网线也被点名!...
  • android中断言_PageObject设计模式在 UI 自动化中的实践(QQ 邮箱登陆为例)
  • 广西中专机器人应用与维护_工业机器人工程师|记工信部考证班结课啦!
  • spring项目中target项目是什么‘’_手把手教你搭建一个SSM项目
  • django 查询时间范围_Django集成OpenLDAP认证
  • thrift端口未被占用连接不上_跨语言RPC框架:Thrift的使用例子解析(包含完整项目源码)...
  • 分享一款快速APP功能测试工具
  • Angular6错误 Service: No provider for Renderer2
  • canvas 高仿 Apple Watch 表盘
  • Java IO学习笔记一
  • JavaScript设计模式系列一:工厂模式
  • session共享问题解决方案
  • 服务器之间,相同帐号,实现免密钥登录
  • 基于web的全景—— Pannellum小试
  • 开年巨制!千人千面回放技术让你“看到”Flutter用户侧问题
  • 利用jquery编写加法运算验证码
  • 使用 Node.js 的 nodemailer 模块发送邮件(支持 QQ、163 等、支持附件)
  • 微信小程序--------语音识别(前端自己也能玩)
  • 小程序滚动组件,左边导航栏与右边内容联动效果实现
  • 学习笔记DL002:AI、机器学习、表示学习、深度学习,第一次大衰退
  • 赢得Docker挑战最佳实践
  • 鱼骨图 - 如何绘制?
  • 自定义函数
  • Prometheus VS InfluxDB
  • UI设计初学者应该如何入门?
  • 回归生活:清理微信公众号
  • ​总结MySQL 的一些知识点:MySQL 选择数据库​
  • #if #elif #endif
  • (十二)springboot实战——SSE服务推送事件案例实现
  • (十一)手动添加用户和文件的特殊权限
  • (一)为什么要选择C++
  • .NET Standard / dotnet-core / net472 —— .NET 究竟应该如何大小写?
  • .net 逐行读取大文本文件_如何使用 Java 灵活读取 Excel 内容 ?
  • .NET国产化改造探索(一)、VMware安装银河麒麟
  • .NET性能优化(文摘)
  • .pyc文件是什么?
  • .xml 下拉列表_RecyclerView嵌套recyclerview实现二级下拉列表,包含自定义IOS对话框...
  • [.net]官方水晶报表的使用以演示下载
  • [Big Data - Kafka] kafka学习笔记:知识点整理
  • [bug总结]: Feign调用GET请求找不到请求体实体类
  • [bzoj1006]: [HNOI2008]神奇的国度(最大势算法)
  • [C++参考]拷贝构造函数的参数必须是引用类型
  • [CVPR2021]Birds of a Feather: Capturing Avian Shape Models from Images
  • [HNOI2008]Cards
  • [HTML]Web前端开发技术18(HTML5、CSS3、JavaScript )HTML5 基础与CSS3 应用——喵喵画网页
  • [LeetCode] Verify Preorder Sequence in Binary Search Tree 验证二叉搜索树的先序序列