使用webpack4 + babel7来生成自己的js库,同时加入eslint校验,jsdoc生成,单元测试。
需求
公司之前的js库是手写的,使用的是es5代码,手动做的模块划分,没有模块化的概念,本次使用webpack4 + babel7 来构建这个js库。
如果不使用webpack,babel可以单独的转译单个es6文件为es5代码,但是没有模块化的功能,这里结合webpack和babel,可以实现定制化的需求。
准备
- 建立个文件夹,使用如下命令生成
packge.json
文件
npm init -y
- 需要安装如下几个依赖:
webpack //打包工具
webpack-cli //webpack4 之后都要装这个
babel-loader //webpack loader,来处理 es代码
@babel/cli //babel7
@babel/core
@babel/polyfill
@babel/runtime
npm i webpack webpack-cli @babel/cli @babel/core babel-loader --save-dev
npm i @babel/polyfill @babel/runtime --save
3.安装完成之后,我们建立几个子文件夹,如下
+---- build #放webpack配置文件
+---- dist #打包输出文件
+---- src #源代码文件夹
在src文件夹下建一个lib文件夹文件,在lib文件夹建一个tools.js文件,写几个es6代码:
/* tools.js */
export function getName(){
return 'abc';
}
然后在src文件index.js文件,引入刚才的tools.js:
/* index.js */
import * as tools from './lib/tools';
export {
tools
}
相当于导出了一个模块,模块名叫tools
, 里面有个函数叫getName
。
导出
接下来我们要把这个模块导出成es5的代码。
在build
文件夹新建一个webpack的配置文件webpack.config.js
, 内容如下:
const path = require('path');
module.exports ={
mode: 'production', // 生产环境,压缩代码
entry: ['./src/index.js'], //入口
output: {
library: 'oreo', // 库名字, 取名叫oreo(奥利奥), 可以直接调用,比如window.oreo
libraryTarget: 'umd', // 输出library规范代码, umd是兼容amd和cmd的
path: path.resolve(__dirname, '../dist'), // 输出路径
filename: 'oreo.js' // 文件名
},
devtool: 'source-map',
module: {
rules: [
{
test: /\.js$/,
include: [
path.resolve(__dirname, 'src')
],
exclude: /node_modules/,
use: {
loader: 'babel-loader' // 使用babel-loader处理es代码
}
}
]
}
};
执行命令,就可以生成了。
webpack --config build/webpack.config.js
或者直接把这个命令行放到package.json
的 npm scripts
里面
"scripts": {
"build": "webpack --config build/webpack.config.js"
}
直接执行npm run build
就可以了,webapck就会把编译好的文件输出在dist文件夹。
可以直接被html
引用:
<script src="../dist/oreo.js"></script>
<script>
console.log(oreo.tools.getName()); //输出abc
</script>
也可以直接用作模块被其他模块使用import导入
把package.json
的项目入口文件改成之前定义的index.js
{
"name": "oreo",
"version": "0.0.1",
"description": "oreo测试",
"main": "src/index.js",
}
发布到npm服务器后,被引入到另外一个项目
import * as orea from 'oreo' ; //假设我们的模块名字叫oreo,被其他项目引用
console.log(oreo.tools.getName()); //输出abc
为库加入eslint
代码审查
既然是用作js基础库,必定要保证质量,这里用eslint来进行代码审查
安装:
npm i eslint --save-dev
安装完成时候我们在根目录建一个.eslintrc.js
文件。该文件是eslint的配置文件
module.exports = {
env: { //环境
browser: true,
es6: true
},
extends: "eslint:recommended", // 官方推荐的校验配置
globals: { // 预设一些全局变量,eslint校验这些
"Atomics": "readonly",
"SharedArrayBuffer": "readonly"
},
parserOptions: {
"ecmaVersion": 2018,
"sourceType": "module"
},
rules: { // 规则
/* 风格 */
'indent': [0, 4], // 4个空格缩进
'semi': [1, 'always'], // 结尾使用分号
}
};
我们可以在package.json
的 npm scripts
里面加入命令行:
// eslint命令后面是要审查的目录
"scripts": {
"lint": "eslint src/**"
}
执行npm run lint
,就可以查看控制台的校验信息了,如果不符合rules定义的规范,控制台会打印一下信息。具体的配置可以到 eslint中文网查看详细文档。
我们也可以在webpack生成之前做审核,这个需要eslint-loader
插件,我们来安装它
npm i eslint-loader --save-dev
我们在webpack.config.js
里面加入eslint-loader
module: {
rules: [
{
//前置(在执行编译之前去执行eslint-loader检查代码规范,有报错就不执行编译)
test: /.(js)$/,
enforce: 'pre', // 在执行编译之前去执行eslint-loader检查代码规范,有报错就不执行编译
exclude: /node_modules/,
loader: "eslint-loader",
options: {
formatter: function(results) {
return "output";
}
}
}
// ...其他代码
]
},
执行npm run build
就可以在编译之前进行eslint校验了。
根据jsdoc生成文档
jsdoc是一个js注释生成文档的方案,最新版是jsdoc3,ink-docstrap是配套的一个主题,我们可以使用jsdoc3+ ink-docstrap来自动生成js文档。
首选安装它们
npm i jsdoc ink-docstrap --save-dev
然后我们在项目根目录创建一个名字为docs
的文件夹, 用来放置我们输出的文档。然后在项目根目录再建一个jsdoc的配置文件jsdoc.config.json
。
{
"tags": {
"allowUnknownTags": true // 允许未知的tag
},
"source": {
"include": [ //需要生成文档的文件夹列表
"src"
],
"exclude": [ //排除某些文件
"src/index.js",
"src/whale.js"
],
"includePattern": ".+\\.(js|es)$" //正则匹配的文件才会被生成文档
},
"plugins": [
"plugins/markdown" // markdown插件
],
"markdown": { // markdown配置
"tags": [
"file"
],
"excludeTags": [
"author"
],
"parser": "gfm",
"hardwrap": true
},
"templates": {
"cleverLinks": false,
"monospaceLinks": false,
"dateFormat": "ddd MMM Do YYYY",
"outputSourceFiles": true,
"outputSourcePath": true,
"systemName": "common文档", // 标题
"footer": "",
"copyright": "https://docs.qianxiangbank.com",
"navType": "inline",
"theme": "cerulean", // 主题名,ink-docstrap提供的
"linenums": true,
"collapseSymbols": false,
"inverseNav": true,
"protocol": "html://",
"methodHeadingReturns": false
},
"opts": {
"template": "./node_modules/ink-docstrap/template", // 模板路径,ink-docstrap提供的
"destination": "./docs/", //输出路径
"recurse": true, //是否递归
"debug": true,
"readme": "README.md" //要转换的readme文件
}
}
外面直接把启动命令放到package.json
的 npm scripts
里面
"scripts": {
"doc": "jsdoc -c jsdoc.config.json",
}
执行命令 npm run doc
就可以生成文档了。
加入单元测试框架(Karma + Mocha + chai)
为了验证代码写的是否正确,时常需要引入单元测试,这里就为我们的js库引入Karma+Mocha+chai, Karma提供了测试环境,Mocha是单元测试框架,chai是断言库。在这里Karma会启动浏览器环境,运行Mocha测试用例,然后使用chai来进行判断。
首先我们还是需要安装一些东西:
Mocha + chai:
npm i mocha chai --save-dev
Karma:
npm i karma karma-webpack karma-mocha karma-chrome-launcher karma-chai --save-dev
我们在项目根目录建一个配置文件,名字叫karma.config.js
// file : karma.config.js
// Karma configuration
module.exports = function (config) {
config.set({
// base path that will be used to resolve all patterns (eg. files, exclude)
basePath: "",
client: {
captureConsole: true // 设置由 terminal 捕捉 browser 的输出
},
browserConsoleLogOptions: {
level: "log",
format: "%b %T: %m",
terminal: true
},
// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ["mocha", "chai"],
// list of files / patterns to load in the browser
files: [
"./test/*.test.js" // test文件夹下任意层级的.js文件 将要被测试
],
// 排除文件
exclude: [
"karma.config.js"
],
// preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
// 要被浏览器正常的测试,有些js代码需要被转成es5,这里需要定义这个预处理器
preprocessors: {
"src/**/*.js": ["webpack"],
"test/*.test.js": ["webpack"]
},
// karma 插件
plugins: [
"karma-webpack",
"karma-mocha",
"karma-chrome-launcher",
"karma-chai"
],
webpack: {
mode: 'development',
module: {
rules: [
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: [
{
loader: 'babel-loader'
},
]
},
]
}
},
webpackServer: {
noInfo: true
},
// test results reporter to use
// possible values: "dots", "progress"
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
reporters: ["dots"],
// web server port
port: 9876,
// enable / disable colors in the output (reporters and logs)
colors: true,
// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_LOG,
// enable / disable watching file and executing tests whenever any file changes
autoWatch: true,
// start these browsers
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
browsers: ["Chrome"],
// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: false,
// Concurrency level
// how many browser should be started simultaneous
concurrency: Infinity
})
};
配置文件完成之后,我们需要写一些测试文件。
在根目录下面建一个test文件夹,创建一个toos.test.js文件
import * as tools from "../src/lib/tools";
const expect = require('chai').expect; // chai
describe('tools.js测试', function () {
describe('getName函数测试', function () {
it('返回值测试通过', function () {
expect(tools.getName()).to.be.equal('abc');;
});
});
});
我们仍然把启动命令行放到package.json
的 npm scripts
里面
"scripts": {
"test": "karma start karma.config.js",
},
执行命令npm run test
就可以唤起chrome
浏览器进行测试了。
如果控制台没有提示报错,就意味着单元测试通过。
如果我们只需要在node环境下进行测试,其实不需要karma,只需要Mocha+chai 就可以完成了。
"scripts": {
"mocha-test": "mocha --require @babel/register"
},
执行命令npm run mocha-test
就可以在node环境下测试了。