注:正像該系列(零)《擴展篇》裏提到的,單測和eslint並非必須,但是對於項目的管理還是有必要引入的。
1、安裝單測和eslint的依賴
eslint的安裝跟從零搭建前端開發環境(零)——擴展篇:4.eslint統一代碼規範裏面的差不多(如果看不懂本文的一些上下文,請先看這篇),不過我們這回用的是eslint-config-airbnb,查看依賴和分版本安裝具體步驟就不說了 直接上結果安裝。
$ npm i -D jest babel-jest enzyme-adapter-react-16 enzyme eslint-config-airbnb [email protected] [email protected] [email protected] [email protected] eslint-loader
2、配置react的eslint
.eslintrc.js
const path = require('path');
const root = __dirname;
module.exports = {
root: true,
extends: 'airbnb',
parserOptions: {
ecmaVersion: 2017, // ES8
sourceType: 'module',
ecmaFeatures: {
jsx: true,
// 啓用對實驗性的 object rest/spread properties 支持。該語法在 ecmaVersion: 2018 中得到支持。該選項在未來將被移除。
experimentalObjectRestSpread: true
}
},
env: {
browser: true,
node: true,
jest: true
},
settings: {
'import/resolver': {
webpack: {
config: path.resolve(root, 'config/webpack.base.js')
}
}
},
rules: {
'max-len': 0,
'jsx-a11y/anchor-is-valid': [ 'error', {'components': []}], // react-router <Link />
'react/prop-types': ['error', { ignore: ['match']}] // react-router props.match
}
}
本來打算把redux和react-router另起一篇寫的,但是在配置方面實在就這麼點東西,rules裏面的規則就是適配react-router4的,另外我把每行100字符以內的限制也給關掉了,大家根據自己的需求來設置吧。另外還需添加.eslintignore,修改webpack.base.js,詳見從零搭建前端開發環境(零)——擴展篇:4.eslint統一代碼規範。來感受史上最嚴格規範的恐怖吧~~
3、jest + enzyme用例
細節可參考用jest構建react項目的測試框架——安裝與配置和,此處會有些許不一樣的地方,領會精神即可。把jest的配置和test下面的配置文件列出來,用例就不貼上來了。
config/jest.config.js
const path = require('path');
module.exports = {
rootDir: path.resolve(__dirname, '../'),
collectCoverage: true, // 是否收集測試時的覆蓋率信息
collectCoverageFrom: ['<rootDir>/src/**/*.{js,jsx,mjs}'], // 哪些文件需要收集覆蓋率信息
coverageDirectory: '<rootDir>/test/coverage', // 輸出覆蓋信息文件的目錄
coveragePathIgnorePatterns: ['/node_modules/', '<rootDir>/src/index.jsx'], // 統計覆蓋信息時需要忽略的文件
moduleNameMapper: { // 主要用於與webpack的resolve.alias匹配,注意正則寫法
'^src/(.*)$': '<rootDir>/src/$1',
'^util/(.*)$': '<rootDir>/src/util/$1',
'^assets/(.*)$': '<rootDir>/src/assets/$1',
'^components/(.*)$': '<rootDir>/src/components/$1',
},
setupFiles: ['<rootDir>/test/setup.js'], // 運行測試前可運行的腳本,比如註冊enzyme的兼容
testMatch: [ // 匹配的測試文件
'<rootDir>/test/**/?(*.)(spec|test).{js,jsx,mjs}',
'<rootDir>/src/**/__tests__/**/*.{js,jsx,mjs}',
],
testURL: 'about:blank', // 運行環境下的url
transform: {
'^.+\\.(js|jsx|mjs)$': '<rootDir>/node_modules/babel-jest',
'^.+\\.(css|less)$': '<rootDir>/test/cssTransform.js',
'\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$': '<rootDir>/test/fileTransform.js',
},
transformIgnorePatterns: [ // 轉換時需要忽略的文件
'[/\\\\]node_modules[/\\\\].+\\.(js|jsx|mjs)$',
],
};
test/cssTransform.js
module.exports = {
process() {
return 'module.exports = {};';
},
getCacheKey() {
// The output is always the same.
return 'cssTransform';
},
};
test/fileTransform.js
const path = require('path');
// This is a custom Jest transformer turning file imports into filenames.
// http://facebook.github.io/jest/docs/en/webpack.html
module.exports = {
process(src, filename) {
return `module.exports = ${JSON.stringify(path.basename(filename))};`;
},
};
test/setup.js
import Enzyme from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
Enzyme.configure({ adapter: new Adapter() });
.babelrc
{
"presets": [
["env",{ "modules": false }],
"stage-2",
"react"
],
"env": {
"test": {
"presets": ["env", "stage-2", "react"]
}
}
}