pnpm
过滤器
过滤允许将命令限制于包的特定子集。 可通过 --filter
(或 -F
) 标志制定选择器:
xml
pnpm --filter <package_selector> <command>
匹配
--filter <package_name>
选择准确的包,只用指定其名称或者使用模式来选择一组包。
指定包的范围是可选的,因此如果未找到 core
,--filter=core
将选择 @babel/core
。 但是,如果工作区有多个同名的包(例如,@babel/core
和 @types/core
),则没有范围的过滤将不会选择任何内容。
bash
pnpm --filter "@babel/core" test
pnpm --filter "@babel/*" test
pnpm --filter "*core" test
--filter <package_name>...
要选择一个软件包及其依赖项 (直接和非直接) 在包名称后加上省略号。
bash
pnpm --filter foo... test
pnpm --filter "@babel/preset-*..." test
--filter <package_name>^...
要只选择一个包的依赖项(直接和非直接), 在包名前添加一个山形符号加上上面提到的省略号.
bash
pnpm --filter "foo^..." test
Vue
推荐的组件开发范式 单文件组件 SFC 并不是原生的 Web 开发语法,需要引入相关的 Vite
插件 @vitejs/plugin-vue,这个插件集成了 vue
编译器的能力,使得构建工具能够理解 Vue SFC
模板。
Vite集成
- 编写构建目标源码
- 准备
vite.config
配置文件。 - 在
package.json
中设置构建脚本。
库模式
思路
在项目的根目录安装公共依赖,公司内网的项目可以使用 .npmrc
文件指定特殊网络环境下的 npm
配置
集成 lint 代码规范工具
实现代码风格的规范化
ESLint
在项目的根目录下添加 .eslintrc.js
或 .eslintrc.json
文件,在其中导出配置对象。举个例子ipt-eslint 实现了对 TypeScript 的支持。
ESLint
理解代码?
parser
和 parserOptions
选项与 ESLint
理解代码有关。分析器 @typescript-eslint/parser
负责解析 TypeScript
语言,将代码转化为 AST 语法树,便于进行分析。而 parserOptions
可以对解析器的能力进行详细设置。
- ESLint 如何判断代码是否规范?
ESLint
提供了 自定义规则 的接口,开发者需要遵照接口,根据分析器的 AST 产物,实现规范检查逻辑,再将实现的多条规范聚合为 plugin
插件的形式,plugin
字段指定了 ESLint
应用什么规则集。
- 规则的启用与禁用
在 rules
字段中对这些规则进行开启或者关闭的声明,只有开启的规则才会生效
- 继承已有配置
社区出了许多配置预设,例子中的 eslint:recommended
、plugin:@typescript-eslint/recommended
就代表继承了 eslint
和 typescript-eslint
的推荐配置。
- 配置的重写
某些文件应用一些独特的配置,可以使用 overrides
字段实现.
perl
{
"root": true,
// 继承已有配置对象
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended"
],
// 如何理解代码
"parser": "@typescript-eslint/parser",
"parserOptions": { "project": ["./tsconfig.json"] },
// 添加哪些规则
"plugins": [
"@typescript-eslint"
],
// 已添加规则的开启 / 关闭
"rules": {
"@typescript-eslint/strict-boolean-expressions": [
2,
{
"allowString" : false,
"allowNumber" : false
}
]
},
// 对特殊文件应用特殊配置
"overrides": [
{
"files": ["*.vue"],
"rules": {
// 所有 .vue 文件除了应用上面的公共规则配置外,还需应用的独特规则配置。
},
},
],
}
规则集的选型
Airbnb
的规则
配置
javascript
const { defineConfig } = require('eslint-define-config');
const path = require('path');
module.exports = defineConfig({
// 指定此配置为根级配置,eslint 不会继续向上层寻找
root: true,
// 将浏览器 API、ES API 和 Node API 看做全局变量,不会被特定的规则(如 no-undef)限制。
//设置代码运行环境的配置选项
env: {
//指定代码将在浏览器环境中运行
browser: true,
es2022: true,
node: true,
},
// 设置自定义全局变量,不会被特定的规则(如 no-undef)限制。
globals: {
// 假如我们希望 jquery 的全局变量不被限制,就按照如下方式声明。
// $: 'readonly',
},
// 集成 Airbnb 规则集以及 vue 相关规则
extends: [
'airbnb-base',
'airbnb-typescript/base',
'plugin:vue/vue3-recommended',
],
// 指定 vue 解析器
parser: 'vue-eslint-parser',
parserOptions: {
// 配置 TypeScript 解析器
parser: '@typescript-eslint/parser',
// 通过 tsconfig 文件确定解析范围,这里需要绝对路径,否则子模块中 eslint 会出现异常
project: path.resolve(__dirname, 'tsconfig.eslint.json'),
// 支持的 ecmaVersion 版本
ecmaVersion: 13,
// 我们主要使用 esm,设置为 module
sourceType: 'module',
// TypeScript 解析器也要负责 vue 文件的 <script>
extraFileExtensions: ['.vue'],
},
// 在已有规则及基础上微调修改
rules: {
'import/no-extraneous-dependencies': 'off',
'import/prefer-default-export': 'off',
// vue 允许单单词组件名
'vue/multi-word-component-names': 'off',
'operator-linebreak': ['error', 'after'],
'class-methods-use-this': 'off',
// 允许使用 ++
'no-plusplus': 'off',
'no-spaced-func': 'off',
// 换行符不作约束
'linebreak-style': 'off',
},
// 文件级别的重写
overrides: [
// 对于 vite 和 vitest 的配置文件,不对 console.log 进行错误提示
{
files: [
'**/vite.config.*',
'**/vitest.config.*',
],
rules: {
'no-console': 'off',
},
},
],
})
Stylelint
Stylelint 是一个强大的 CSS 格式化工具,可以帮助使用者避免语法错误并统一编码风格。
gulp的使用
创建一个任务Task
每个gulp任务(task)都是一个异步的JavaScript函数,此函数是一个可以接收callback作为参数的函数,或者返回一个Promise等异步操作对象。
在 Gulp 构建工具中,gulp
模块是用于定义任务和构建工作流的核心模块。通过使用 require("gulp")
语句,我们可以在 Node.js 环境中引入并使用 Gulp 模块。
series
和 parallel
是 gulp
模块提供的两个重要的函数,它们用于定义任务执行的方式。
series
函数用于将多个任务按照顺序串行执行。例如,series(task1, task2)
将依次执行task1
和task2
,确保前一个任务完成后再执行下一个任务。parallel
函数用于将多个任务并行执行。例如,parallel(task1, task2)
将同时执行task1
和task2
,无需等待前一个任务完成。pipe
是 Gulp 中一个非常常用的方法,它用于将文件流传递给下一个 Gulp 插件或操作。在 Gulp 的任务中,我们可以使用pipe
方法将文件流通过一系列的插件进行处理和转换。
javascript
const { series, parallel } = require("gulp");
const { resolve } = require("path");
const task1 = () => {
console.log("task1");
return new Promise((resolve) => {
setTimeout(() => {
resolve();
}, 5000);
});
};
const task2 = () => {
console.log("task2");
return Promise.resolve();
};
exports.default = series(task1, task2);
exports.default = parallel(task1, task2);
src()和dest()
src()和dest()这两个函数在我们实际项目中经常会用到。src()表示创建一个读取文件系统的流,dest()是创建一个写入到文件系统的流。
处理less文件
安装gulp-less
css
npm i -D gulp-less
bash
然后我们在src下新建一个style/index.less并写下一段less语法样式
less
@color: #fff;
.wrap {
color: @color;
}
然后gulpfile.js写下我们的lessTask:将我们style下的less文件解析成css并写入dist/style中
ini
const { src, dest } = require("gulp");
const less = require("gulp-less");
const lessTask = () => {
return src("src/style/*.less").pipe(less()).pipe(dest("dist/style"));
};
exports.default = lessTask;
然后我们执行gulp命令就会发现dist/style/index.css
css
.wrap {
color: #fff;
}
监听文件更改browser-sync
browser-sync是一个十分好用的浏览器同步测试工具,它可以搭建静态服务器,监听文件更改,并刷新页面(HMR) 要先安装
css
npm i browser-sync -D
然后我们在根目录下新建index.html
xml
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
hello world
</body>
</html>
然后在gulpfile.js 中进行配置 流程是 编译less文件 ->将css写入dist/style ->触发页面更新
javascript
const { src, dest } = require("gulp");
const { watch } = require("browser-sync");
const browserSync = require("browser-sync");
const { series } = require("gulp");
const less = require("gulp-less");
const autoprefixer = require("gulp-autoprefixer");
const lessTask = () => {
return src("src/style/*.less")
.pipe(less())
.pipe(
autoprefixer({
overrideBrowserslist: ["> 1%", "last 2 versions"],
cascade: false, // 是否美化属性值
})
)
.pipe(dest("dist/style"));
};
//页面刷新
const reloadTask = () => {
browserSync.reload();
};
const browserTask = () => {
browserSync.init({
server: {
baseDir: "./",
},
});
watch("./*.html", series(reloadTask));
//监听样式更新触发两个任务
watch("src/style/*", series(lessTask, reloadTask));
};
exports.default = browserTask;