使用webpack4 + babel7來生成自己的js庫吩案,同時加入eslint校驗,jsdoc生成帝簇,單元測試徘郭。
需求
公司之前的js庫是手寫的,使用的是es5代碼丧肴,手動做的模塊劃分残揉,沒有模塊化的概念,本次使用webpack4 + babel7 來構建這個js庫芋浮。
如果不使用webpack抱环,babel可以單獨的轉譯單個es6文件為es5代碼,但是沒有模塊化的功能纸巷,這里結合webpack和babel镇草,可以實現(xiàn)定制化的需求。
準備
- 建立個文件夾瘤旨,使用如下命令生成
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
, 里面有個函數(shù)叫getName
。
導出
接下來我們要把這個模塊導出成es5的代碼肩袍。
在build
文件夾新建一個webpack的配置文件webpack.config.js
, 內容如下:
const path = require('path');
module.exports ={
mode: 'production', // 生產環(huán)境杭棵,壓縮代碼
entry: ['./src/index.js'], //入口
output: {
library: 'oreo', // 庫名字, 取名叫oreo(奧利奧), 可以直接調用,比如window.oreo
libraryTarget: 'umd', // 輸出library規(guī)范代碼, 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代碼
}
}
]
}
};
執(zhí)行命令,就可以生成了氛赐。
webpack --config build/webpack.config.js
或者直接把這個命令行放到package.json
的 npm scripts
里面
"scripts": {
"build": "webpack --config build/webpack.config.js"
}
直接執(zhí)行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",
}
發(fā)布到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: { //環(huán)境
browser: true,
es6: true
},
extends: "eslint:recommended", // 官方推薦的校驗配置
globals: { // 預設一些全局變量旬痹,eslint校驗這些
"Atomics": "readonly",
"SharedArrayBuffer": "readonly"
},
parserOptions: {
"ecmaVersion": 2018,
"sourceType": "module"
},
rules: { // 規(guī)則
/* 風格 */
'indent': [0, 4], // 4個空格縮進
'semi': [1, 'always'], // 結尾使用分號
}
};
我們可以在package.json
的 npm scripts
里面加入命令行:
// eslint命令后面是要審查的目錄
"scripts": {
"lint": "eslint src/**"
}
執(zhí)行npm run lint
,就可以查看控制臺的校驗信息了吕粗,如果不符合rules定義的規(guī)范试读,控制臺會打印一下信息锨咙。具體的配置可以到 eslint中文網查看詳細文檔嘶炭。
我們也可以在webpack生成之前做審核,這個需要eslint-loader
插件歹鱼,我們來安裝它
npm i eslint-loader --save-dev
我們在webpack.config.js
里面加入eslint-loader
module: {
rules: [
{
//前置(在執(zhí)行編譯之前去執(zhí)行eslint-loader檢查代碼規(guī)范泣栈,有報錯就不執(zhí)行編譯)
test: /.(js)$/,
enforce: 'pre', // 在執(zhí)行編譯之前去執(zhí)行eslint-loader檢查代碼規(guī)范,有報錯就不執(zhí)行編譯
exclude: /node_modules/,
loader: "eslint-loader",
options: {
formatter: function(results) {
return "output";
}
}
}
// ...其他代碼
]
},
執(zhí)行npm run build
就可以在編譯之前進行eslint校驗了弥姻。
根據(jù)jsdoc生成文檔
jsdoc是一個js注釋生成文檔的方案南片,最新版是jsdoc3,ink-docstrap是配套的一個主題蚁阳,我們可以使用jsdoc3+ ink-docstrap來自動生成js文檔铃绒。
首選安裝它們
npm i jsdoc ink-docstrap --save-dev
然后我們在項目根目錄創(chuàng)建一個名字為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",
}
執(zhí)行命令 npm run doc
就可以生成文檔了定血。
加入單元測試框架(Karma + Mocha + chai)
為了驗證代碼寫的是否正確赔癌,時常需要引入單元測試,這里就為我們的js庫引入Karma+Mocha+chai澜沟, Karma提供了測試環(huán)境灾票,Mocha是單元測試框架,chai是斷言庫茫虽。在這里Karma會啟動瀏覽器環(huán)境刊苍,運行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文件夾盾致,創(chuàng)建一個toos.test.js文件
import * as tools from "../src/lib/tools";
const expect = require('chai').expect; // chai
describe('tools.js測試', function () {
describe('getName函數(shù)測試', function () {
it('返回值測試通過', function () {
expect(tools.getName()).to.be.equal('abc');;
});
});
});
我們仍然把啟動命令行放到package.json
的 npm scripts
里面
"scripts": {
"test": "karma start karma.config.js",
},
執(zhí)行命令npm run test
就可以喚起chrome
瀏覽器進行測試了主经。
如果控制臺沒有提示報錯,就意味著單元測試通過庭惜。
如果我們只需要在node環(huán)境下進行測試罩驻,其實不需要karma,只需要Mocha+chai 就可以完成了蜈块。
"scripts": {
"mocha-test": "mocha --require @babel/register"
},
執(zhí)行命令npm run mocha-test
就可以在node環(huán)境下測試了鉴腻。