用
ES6
編寫程式碼,使用Webpack
打包匯出模組,併發布到NPM社群,新增基於Travis-CI
和Coveralls
的持續整合到Github專案中
特性
- 基於Webpack 4
- 使用ES6編寫原始碼
- 模組支援:
- 使用 AVA 自動化測試,並通過 nyc 測試程式碼覆蓋率
- 持續整合(Travis-CI + Coveralls)
- 使用 ESLint + Standrad 檢測程式碼質量
專案初始化
1. 建立repository並clone到本地
$ git clone https://github.com/eteplus/typeof
複製程式碼
2. 新增.editorconfig
root = true
[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.yml]
indent_style = space
indent_size = 2
複製程式碼
3. 建立目錄
+-- src 原始碼目錄
| +-- typeof.js
| +-- types.js
+-- test 測試用例
| +--- test.js
+-- dist 輸出目錄
.
.
複製程式碼
4. 建立package.json
使用NPM作用域管理髮布模組,避免同名模組,一般使用使用者名稱來註冊私有模組(
@eteplus/<package name>
)
$ npm init --scope=eteplus
複製程式碼
package name: (@eteplus/typeof)
version: (1.0.0) 0.1.0
description: The typeOf method returns a string indicating the type of the value
entry point: (index.js) dist/typeof.js
test command:
git repository: https://github.com/eteplus/typeof.git
keywords: node,javascript,typeof
author: eteplus
license: (ISC) MIT
About to write to /Users/eteplus/Workspace/Node/study/typeof/package.json:
{
"name": "@eteplus/typeof",
"version": "0.1.0",
"description": "The typeOf method returns a string indicating the type of the value",
"main": "dist/typeof.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/eteplus/typeof.git"
},
"keywords": [
"node",
"javascript",
"typeof"
],
"author": "eteplus",
"license": "MIT",
"bugs": {
"url": "https://github.com/eteplus/typeof/issues"
},
"homepage": "https://github.com/eteplus/typeof#readme"
}
複製程式碼
5. ESLint 初始化
自動生成
.eslintrc.js
檔案並安裝相關依賴(可根據自己喜好選擇程式碼規範)
- 安裝ESlint
# or use yarn
$ npm install eslint -D
複製程式碼
$ npm install eslint -g # 全域性安裝ESLint
$ eslint --init
? How would you like to configure ESLint? Use a popular style guide
? Which style guide do you want to follow? Standard
? What format do you want your config file to be in? JavaScript
複製程式碼
- 新增
.eslintignore
檔案忽略對輸出目錄的程式碼檢測
dist/
複製程式碼
6. 建立webpack和babel的配置檔案
- 安裝相關依賴:
$ npm install webpack webpack-cli uglifyjs-webpack-plugin -D
$ npm install babel-loader babel-core babel-plugin-transform-runtime babel-preset-env -D
$ npm install eslint-loader eslint-friendly-formatter -D
複製程式碼
- 建立 webpack.config.js:
webpack output 配置項說明 webpack.js.org/configurati…
'use strict'
const path = require('path')
const webpack = require('webpack')
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
const resolve = dir => path.join(__dirname, '.', dir)
const isProd = process.env.NODE_ENV === 'production'
module.exports = {
entry: {
typeof: './src/typeof.js'
},
output: {
path: resolve('dist'), // 輸出目錄
filename: '[name].js', // 輸出檔案
libraryTarget: 'umd', // 採用通用模組定義
library: 'typeOf', // 庫名稱
libraryExport: 'default', // 相容 ES6(ES2015) 的模組系統、CommonJS 和 AMD 模組規範
globalObject: 'this' // 相容node和瀏覽器執行,避免window is not undefined情況
},
devtool: '#source-map',
module: {
rules: [
{
test: /\.(js)$/,
loader: 'eslint-loader',
enforce: 'pre',
include: [resolve('src'), resolve('test')],
options: {
formatter: require('eslint-friendly-formatter')
}
},
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /(node_modules)/
}
]
},
plugins: isProd
? [
new UglifyJsPlugin({
parallel: true,
uglifyOptions: {
compress: {
warnings: false
},
mangle: true
},
sourceMap: true
})
]
: [
new webpack.HotModuleReplacementPlugin(),
new webpack.NamedModulesPlugin(),
new webpack.NoEmitOnErrorsPlugin()
]
}
複製程式碼
- 建立 .babelrc:
heplers和polyfill根據實際情況開啟/關閉,具體配置參考(babel-plugin-transform-runtime)
{
"presets": ["env"],
"plugins": [
["transform-runtime", {
"helpers": false,
"polyfill": false
}
]
]
}
複製程式碼
7. 新增npm命令
在package.json上新增npm命令,通過npm run [name] 執行任務
{
"scripts": {
"dev": "NODE_ENV=development webpack --config webpack.config.js --mode=development -w",
"build": "NODE_ENV=production webpack --config webpack.config.js --mode=production",
"lint": "eslint ."
}
}
複製程式碼
測試與程式碼覆蓋率
1. 安裝AVA 和 nyc
$ npm install ava nyc -D
複製程式碼
2. 新增ava和nyc配置到package.json
AVA:
- files:需要測試的用例檔案
- verbose:開啟詳細輸出
- babel:測試檔案的babel配置,'inherit'使用根目錄下的.babelrc
- require:執行測試前需要額外的模組
其他配置項:
nyc:
{
"ava": {
"files": [
"test/test.js"
],
"verbose": true,
"babel": "inherit",
"require": [
"babel-core/register"
]
},
"nyc": {
"exclude": [
"test/*.js"
]
}
}
複製程式碼
3. 新增npm命令
{
"scripts": {
...
"test": "npm run lint && nyc ava",
"test:watch": "ava --watch"
}
}
複製程式碼
持續整合Travis CI
1. 登陸Travis-CI
travis-ci.org,使用Github授權登陸
2. 新增Repo
3. 建立.travis.yml
在專案根目錄下新增
.travis.yml
說明:
- language 指定開發語言
- node_js 指定node.js版本號
其它配置項:
language: node_js
node_js:
- '9'
- '8'
- '7'
複製程式碼
4. 提交.travis.yml
提交
.travis.yml
到Github, Travis-CI根據提交自動觸發持續整合,可在設定中取消根據提交自動觸發持續整合
5. 獲取徽章
獲取持續整合結果徽章新增到
README.md
中
測試覆蓋率Coveralls
1. 登陸Coveralls
coveralls.io,使用Github授權登陸
2. 新增Repo
3. 加密repo_token
安全起見,repo_token不應該明文寫到
.travis.yml
中,coveralls提供了非對稱加密repo_token的方法
- 使用travis命令工具加密
# 更改為國內的安裝源
$ gem sources --add https://gems.ruby-china.org/ --remove https://rubygems.org/
$ gem sources -l
複製程式碼
# 安裝travis
$ sudo gem install travis -v 1.8.8 --no-rdoc --no-ri
$ travis version
1.8.8
複製程式碼
# 加密
travis encrypt COVERALLS_REPO_TOKEN=your_repo_token
複製程式碼
- 新增加密後的secure到
.travis.yml
修改
.travis.yml
,設定env環境變數(travis提供的repo_token安全方式之一),也可以使用 --add 自動新增到.travis.yml
中。
4. 安裝coveralls並新增npm命令
- 安裝coveralls
$ npm install coveralls -D
複製程式碼
- 新增npm命令
nyc生成覆蓋率報告推送給coveralls
{
"scripts": {
...
"coverage": "nyc report --reporter=text-lcov | coveralls"
}
}
複製程式碼
5. 修改.travis.yml
- 新增
after_success: npm run coverage
after_success: script階段成功時執行, script階段預設指令碼為
npm test
,可以省略
- 重新提交到Github,觸發持續整合,到coveralls.io檢視覆蓋率報告,並獲取徽章新增到README.md
釋出模組到NPM社群
1. 打包程式碼
$ npm run build
複製程式碼
2. 新增賬號
需要先到www.npmjs.com註冊一個賬號
$ npm adduser
Username: your username
Password: your password
Email: your email
複製程式碼
3. 釋出
無作用域包始終是公開的。有作用域預設為受限制的,可以使用
–-access public
釋出的時候設定許可權為公開
$ npm publish --access public
複製程式碼
npm社群版本號規則採用的是semver(語義化版本),主要規則如下:
版本格式:主版號.次版號.修訂號
版號遞增規則如下:
- 主版號:當你做了不相容的 API 修改,
- 次版號:當你做了向下相容的功能性新增,
- 修訂號:當你做了向下相容的問題修正。
- 先行版號及版本編譯資訊可以加到「主版號.次版號.修訂號」的後面,作為延伸
新增個性化徽章
推薦 shields.io/
為專案新增上各種各樣的徽章,例如:
- 測試是否通過以及程式碼覆蓋率情況
- 專案的最新版本
- 專案的被使用情況
- 程式碼風格
- 專案的開源協議
示例專案
該專案包含教程所有的完整配置
Github地址: github.com/eteplus/typ…