一、概念
命令行界面(英语:command-line interface,缩写:CLI),俗称脚手架。
1、基本工作流程
- 通过命令行交互询问用户问题
- 根据用户回答的结果生成文件
2、热门工具
| 名称 | 简介 | | —- | —- | | commander | 命令行自定义指令 | | inquirer | 命令行询问用户问题,记录回答结果 | | chalk | 控制台输出内容样式美化 | | ora | 控制台 loading 样式 | | figlet | 控制台打印 logo | | easy-table | 控制台输出表格 | | download-git-repo | 下载远程模版 | | fs-extra | 系统fs模块的扩展,提供了更多便利的 API,并继承了fs模块的 API | | cross-spawn | 支持跨平台调用系统上的命令 |
二、vue/cli 配置
1、初始化
- 通过npx
- 执行:
npx @vue/cli create my-project
- 执行:
2、配置选择
- default 配置
- Babel:即ESNext,可使用下一代 JavaScript 语法。作为 webpack loader加载
- Eslint:即代码格式检测
手动选择特性:可以选择将已选项保存为一个将来可复用的 preset。
CLI 服务 (
@vue/cli-service) 是一个开发环境依赖。局部安装在每个@vue/cli创建的项目中的一个 npm 包- 构建于 webpack 和 webpack-dev-server 之上
- CLI 插件是提供可选功能的 npm 包,例如 Babel/TypeScript 转译、ESLint 集成、单元测试和 end-to-end 测试等。Vue CLI 插件的名字以
@vue/cli-plugin-(内建插件) 或vue-cli-plugin-(社区插件) 开头 - 项目内部运行
vue-cli-service命令时,它会自动解析并加载package.json中列出的所有 CLI 插件
4、插件
插件可以修改 webpack 的内部配置,也可以向 vue-cli-service 注入命令。每个 CLI 插件包含一个 (用来创建文件的) 生成器和一个 (用来调整 webpack 核心配置和注入命令的) 运行时插件
- 已有项目中安装一个插件:使用
vue add命令,如vue add eslint- 建议先提交项目最新状态,该命令可能调用插件的文件生成器并很有可能更改你现有的文件
- 不带
@vue前缀,该命令会换作解析一个 unscoped 的包,会安装第三方插件 - 插件已经被安装:使用
vue invoke命令跳过安装过程,只调用它的生成器
本地插件:需要每个文件暴露一个函数,接受插件 API 作为第一个参数
{"vuePlugins": {"service": ["my-commands.js"]}}
5、cli服务
vue-cli-service serve:启动一个开发服务器 (基于 webpack-dev-server) 并附带开箱即用的模块热重载 (Hot-Module-Replacement)。也可使用vue.config.js里的 devServer 字段配置开发服务器vue-cli-service build [options]:在dist/目录产生一个可用于生产环境的包,带有 JS/CSS/HTML 的压缩,和为更好的缓存自动的 vendor chunk splitting。它的 chunk manifest 会内联在 HTML 里- vue-cli-service build —modern:产生两个应用的版本,一个现代版的包,面向支持 ES modules 的现代浏览器,另一个旧版的包,面向不支持的旧浏览器。 ``` 用法:vue-cli-service build [options] [entry|pattern]
选项: —modern 面向现代浏览器带自动回退地构建应用 —target app | lib | wc | wc-async (默认值:app) 允许你将项目中的任何组件以一个库或 Web Components 组件的方式进行构建 —report 生成 report.html 以帮助分析包内容 —report-json 生成 report.json 以帮助分析包内容
- `vue-cli-service inspect`:审查一个 Vue CLI 项目的 webpack config<a name="irOLy"></a>### 6、浏览器兼容性<a name="lwT8l"></a>#### 6.1 browserslist`package.json` 文件里的 `browserslist` 字段指定项目的目标浏览器的范围。值会被 @babel/preset-env 和 Autoprefixer 用来确定需转译的 JS 特性和需添加的 CSS 浏览器前缀。如何指定见[browserslist](https://github.com/browserslist/browserslist)<a name="dBP5Y"></a>#### 6.2 polyfill一个默认的 Vue CLI 项目会使用 @vue/babel-preset-app,它通过 `@babel/preset-env` 和 `browserslist` 配置来决定项目需要的 polyfill。- 默认把 `useBuiltIns: 'usage'` 传递给 `@babel/preset-env`,根据源代码中出现的语言特性自动检测需要的 polyfill。确保最终包里 polyfill 数量的最小化。但**如果其中一个依赖需要特殊的 polyfill,默认情况下 Babel 无法将其检测出来**- 如果有依赖需要 polyfill:- **如果该依赖基于一个目标环境不支持的 ES 版本撰写:** 将其添加到 `vue.config.js` 中的 `transpileDependencies` 选项。这会为该依赖同时开启语法转换和根据使用情况检测 polyfill- **如果该依赖交付了 ES5 代码并显式地列出了需要的 polyfill:** 使用 `@vue/babel-preset-app` 的 polyfills 选项预包含所需要的 polyfill。**注意 **`**es.promise**`** 将被默认包含,因为现在的库依赖 Promise很普遍。**```javascript// babel.config.jsmodule.exports = {presets: [['@vue/app', {polyfills: ['es.promise','es.symbol']}]]}
- 如果该依赖交付 ES5 代码,但使用 ES6+ 特性且没有显式地列出需要的 polyfill (例如 Vuetify):请使用
**useBuiltIns: 'entry'**然后在入口文件添加**import 'core-js/stable'; import 'regenerator-runtime/runtime';**。这会根据**browserslist**目标导入所有 polyfill,但是因为包含了一些没有用到的 polyfill 所以最终的包大小可能会增加。- 构建库或是 Web Component 时的 Polyfills:推荐给
@vue/babel-preset-app传入useBuiltIns: false选项。确保库或是组件不包含不必要的 polyfills。通常来说,打包 polyfills 应当是最终使用你的库的应用的责任
- 构建库或是 Web Component 时的 Polyfills:推荐给
7、webpack 相关
7.1 简单的配置方式
configureWebpack 作为对象:将会被 webpack-merge 合并入最终的 webpack 配置
// vue.config.jsmodule.exports = {configureWebpack: {plugins: [new MyAwesomeWebpackPlugin()]}}
configureWebpack 作为函数:基于环境有条件地配置行为或直接修改配置,在环境变量被设置后懒执行
- 函数第一个参数会收到已经解析好的配置config。在函数内可直接修改配置,或返回一个将会被合并的对象
// vue.config.jsmodule.exports = {configureWebpack: config => {if (process.env.NODE_ENV === 'production') {// 为生产环境修改配置...} else {// 为开发环境修改配置...}}}
- 函数第一个参数会收到已经解析好的配置config。在函数内可直接修改配置,或返回一个将会被合并的对象
7.2 链式操作
webpack-chain 库提供一个 webpack 原始配置的上层抽象,使其可以定义具名的 loader 规则和具名插件,并有机会在后期进入这些规则并对它们的选项进行修改。允许更细粒度的控制其内部配置
// vue.config.jsmodule.exports = {chainWebpack: config => {config.module.rule('vue').use('vue-loader').loader('vue-loader').tap(options => {// 修改它的选项...return options})config.module.rule('graphql').test(/\.graphql$/).use('graphql-tag/loader').loader('graphql-tag/loader').end()// 你还可以再添加一个 loader.use('other-loader').loader('other-loader').end()const svgRule = config.module.rule('svg')svgRule.uses.clear()//清除已有的所有 loader。否则接下来 loader 会附加在该规则现有 loader 后// 添加要替换的 loadersvgRule.use('vue-svg-loader').loader('vue-svg-loader')config.plugin('html').tap(args => {//传递给 html-webpack-plugin's 构造函数的新参数args[0].template = '/Users/username/proj/app/templates/index.html'return args})}}
8、多页面打包
多页面:指一个项目多个入口,打包会生成多个html文件,实际开发过程混合在一个项目中开发
在 multi-page 模式下构建应用。每个“page”应该有一个对应的 JavaScript 入口文件。其值应该是一个对象,对象的 key 是入口的名字,value 是:
- 一个指定了
entry,template,filename,title和chunks的对象 (除了entry之外都是可选的); - 或一个指定其
entry的字符串。module.exports = {pages: {index: {// page 的入口entry: 'src/index/main.js',// 模板来源template: 'public/index.html',// 在 dist/index.html 的输出filename: 'index.html',// 当使用 title 选项时,// template 中的 title 标签需要是 <title><%= htmlWebpackPlugin.options.title %></title>title: 'Index Page',// 在这个页面中包含的块,默认情况下会包含// 提取出来的通用 chunk 和 vendor chunk。chunks: ['chunk-vendors', 'chunk-common', 'index']},// 当使用只有入口的字符串格式时,// 模板会被推导为 `public/subpage.html`// 并且如果找不到的话,就回退到 `public/index.html`。// 输出文件名会被推导为 `subpage.html`。subpage: 'src/subpage/main.js'}}
三、create-react-app 配置
1、初始化
创建一个名为 ts-react 的 typescript 项目
- npx:
npx create-react-app ts-react --template typescript
2、tsconfig.json解读
通常 tsconfig.json 文件主要包含两部分内容:指定待编译文件和定义编译选项。compilerOptions 属性作用是配置编译选项。
{"compilerOptions": {"target": "es5", // 目标语言的版本"lib": ["dom","dom.iterable","esnext"], // TS需要引用的库,即声明文件"allowJs": true, // 允许编译器编译JS,JSX文件"skipLibCheck": true, // 忽略所有的声明文件(*.d.ts)的类型检查"esModuleInterop": true, // 允许export=导出,由import from 导入"allowSyntheticDefaultImports": true, // 允许从没有设置默认导出的模块中默认导入"strict": true,"forceConsistentCasingInFileNames": true, // 禁止对同一个文件的不一致的引用"noFallthroughCasesInSwitch": true, // 防止switch语句贯穿(即无break语句后面不会执行)"module": "esnext", // 指定生成代码的模板标准"moduleResolution": "node", // 使用哪种模块解析策略"resolveJsonModule": true, // 是否可以导入 JSON 模块"isolatedModules": true, // 将每个文件作为单独的模块"noEmit": true, // 不生成输出文件"jsx": "react-jsx" // 在 .tsx文件里支持JSX: "React"或 "Preserve"},"include": ["src"]}
3、自定义配置
弹出cra配置,仅能弹出一次:npm run eject
4、react-scripts
- cra项目中的开发依赖项。可运行内置命令行
5、代码规范、Git工作流/提交规范
- 代码格式化工具:prettier
- 安装prettier:
yarn add prettier -D - 配置.prettierrc ```json { “trailingComma”: “es5”, // 在任何可能的多行中,添加es5中被支持的尾逗号,默认none “tabWidth”: 4, // 水平缩进的空格数,默认为 2 “singleQuote”: true, // 是否使用单引号 “jsxBracketSameLine”: false, // 是否多属性html标签的‘>’折行放置 “printWidth”: 100, // 指定代码换行的行长度,超过最大值换行 }
- 安装prettier:
- 代码规范校验工具:**eslint**- Git工作流规范:- **husky**:git hooks工具- 安装:`yarn add husky -D`- 配置:在package.json 文件的scripts配置项添加命令```json"scripts": {"prepare": "husky install"}
- 执行:`yarn prepare`,创建.husky/目录并指定该目录为git hooks所在的目录
lint-staged : pre-commit Hook 脚本,允许我们在 git 中的暂存文件上运行脚本
- 安装:
yarn add lint-staged -D - 配置:
"lint-staged": {"src/**/*.{js,jsx,ts,tsx,json}": ["prettier --write","eslint","git add"]}
- 安装:
pretty-quick
- 安装:
yarn add pretty-quick -D
- 安装:
commitlint : commit-msg Hook脚本,帮助我们在多人开发时,遵守 git 提交约定
- 安装:
yarn add @commitlint/cli @commitlint/config-conventional -D - 配置:在根目录src目录下创建 commitlint.config.js 文件
module.exports = {extends: ["@commitlint/config-conventional"],// 自定义规则,可不填写rules: {'type-enum': [2,'always',['bug', // 此项特别针对bug号,用于向测试反馈bug列表的bug修改情况'feat', // 新功能(feature)'fix', // 修补bug'docs', // 文档(documentation)'style', // 格式(不影响代码运行的变动)'refactor', // 重构(即不是新增功能,也不是修改bug的代码变动)'test', // 增加测试'chore', // 构建过程或辅助工具的变动'revert', // 撤销之前的commit'merge' // 合并分支]]}};
- 安装:
添加钩子: 首先,运行
yarn prepare- commit-msg :
npx husky add .husky/commit-msg "yarn commitlint --edit '$1'"
- pre-commit: 二选一
npx husky add .husky/pre-commit "yarn lint-staged --allow-empty '$1'"npx husky add .husky/pre-commit "yarn pretty-quick --staged"
- commit-msg :
- 添加钩子到git中去:
- 添加 commit-msg 到git中去:
git add .husky/commit-msg - 添加 pre-commit 到git中去:
git add .husky/pre-commit- Git提交规范:commitizen
- 添加 commit-msg 到git中去:
- 安装:
yarn add commitizen cz-conventional-changelog -D - 配置:在package.json中加入以下代码。其中,需要增加一个script,使得我们可以通过执行npm run cm来代替git commit,而path为cz-conventional-changelog包相对于项目根目录的路径
{"scripts": {"commit": "git-cz",},"config": {"commitizen": {"path": "node_modules/cz-conventional-changelog"}}}
自动化版本控制:standard-version 升级版本号、生成 changelog 及 tag
要告知开发服务器在开发中,将任何未知请求代理到您的 API 服务器,在 package.json 中添加一个代理字段:"proxy": "http://localhost:4000"
7、source-map-explorer 分析包大小
- 安装:
yarn add source-map-explorer- package.json配置加上脚本: ```json “scripts”: {
“analyze”: “source-map-explorer ‘build/static/js/*.js’”, “start”: “react-scripts start”, “build”: “react-scripts build”, “test”: “react-scripts test” }
- 执行:```powershellnpm run buildnpm run analyze
- 不安装:
npx source-map-explorer build/static/js/*.js
