文章目录
- Vite 是一个用于现代 JavaScript 应用程序的快速、轻量级的构建工具,其设计目的是易于使用和适用于大型项目。Vite-pretty-lint 是一个插件,可以在基于 Vite 的项目中安装和配置,以便在编写代码时能够自动对代码进行格式化和检查代码。这可以帮助开发人员在开发过程的早期捕获格式化和链接错误,并确保代码库遵循一致的样式。 学习目标: 如何为 vite 项目自动添加 eslint 和 prettier 它的原理是什么 资源: 源码地址:vite-pretty-lint
- 创建一个vite项目: npm init vite 进入项目文件夹下,安装 Vite-pretty-lint: npm init Vite-pretty-lint 执行上面命令后,会提示选择项目类型和你使用的那种包管理器,如图: <img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/9039a03050b04630bbfd7c1ce596e3a1~tplv-k3u1fbpfcp-watermark.image?" alt="" width="70%" /> 施加魔法中,稍等片刻,它给你的项目自动添加上eslint与prettier的配置,懒人福音啊。 <img src="https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/68a1c56111224dcaa3832986665151d0~tplv-k3u1fbpfcp-watermark.image?" alt="" width="40%" />
- 可以发现,执行 npm init Vite-pretty-lint 我们的项目主要发生了如下的变化:
自动生成了配置文件
添加了依赖
其实,实现上述功能所用到的方法这这篇文章 源码共读 - 构建脚手架(2K字长文) 中都有出现,为了加深印象,我们再来复习一遍。
- 找到脚本的入口文件。如图: <img src="https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/1e6858c15aa14a43a459e7a3d1d0b070~tplv-k3u1fbpfcp-watermark.image?" alt="" width="40%" />
- 源码: try { const answers = await askForProjectType(); projectType = answers.projectType; packageManager = answers.packageManager; } catch (error) { console.log(chalk.blue('\n Goodbye!')); return; } const { packages, eslintOverrides } = await import( `./templates/${projectType}.js` ); 询问项目类型,之后根据用户选择的项目类型复制对应的模板文件,询问包管理器类型,用于安装依赖。 // util.js export function askForProjectType() { return enquirer.prompt([ { type: 'select', name: 'projectType', message: 'What type of project do you have?', choices: getOptions(), }, { type: 'select', name: 'packageManager', message: 'What package manager do you use?', choices: ['npm', 'yarn', 'pnpm'], }, ]); } 这里交互式命令提示工具使用的是 enquirer 包。
- exec(`${commandMap[packageManager]}`, { cwd: projectDirectory }, (error) => { if (error) { spinner.error({ text: chalk.bold.red('Failed to install packages!'), mark: '', }); console.error(error); return; } fs.writeFileSync(eslintFile, JSON.stringify(eslint, null, 2)); fs.writeFileSync(prettierFile, JSON.stringify(prettierConfig, null, 2)); fs.writeFileSync(eslintIgnoreFile, eslintIgnore.join('\n')); fs.writeFileSync(viteFile, viteConfig); spinner.success({ text: chalk.bold.green('All done! '), mark: '' }); console.log( chalk.bold.cyan('\n Reload your editor to activate the settings!') ); }); 做完询问工作,使用exec执行命令安装依赖,然后使用 fs.writeFileSync 复制文件。
- export function viteEslint(code) { // 解析配置为抽象语法树 const ast = babel.parseSync(code, { sourceType: 'module', comments: false, }); const { program } = ast; // 将import 声明映射为一个列表 const importList = program.body .filter((body) => { return body.type === 'ImportDeclaration'; }) .map((body) => { delete body.trailingComments; return body; }); // 找到 vite-plugin-eslint 下写入代码 if (importList.find((body) => body.source.value === 'vite-plugin-eslint')) { return code; } const nonImportList = program.body.filter((body) => { return body.type !== 'ImportDeclaration'; }); const exportStatement = program.body.find( (body) => body.type === 'ExportDefaultDeclaration' ); if (exportStatement.declaration.type === 'CallExpression') { const [argument] = exportStatement.declaration.arguments; if (argument.type === 'ObjectExpression') { const plugin = argument.properties.find( ({ key }) => key.name === 'plugins' ); if (plugin) { plugin.value.elements.push(eslintPluginCall); } } } importList.push(eslintImport); importList.push(blankLine); program.body = importList.concat(nonImportList); ast.program = program; return babel.transformFromAstSync(ast, code, { sourceType: 'module' }).code; } parseSync 方法用于解析一串 JavaScript 代码并返回代码的抽象语法树(AST)表示。AST 是一个树状结构,表示代码的结构,它可以用来以各种方式分析或修改代码。 ParseSync 方法有两个参数: Code: 包含要解析的 JavaScript 代码的字符串。 Options: 包含解析器配置选项的可选对象。
- 通过本次课程,不仅学习到了 Vite-pretty-lint 是如何自动配置eslint与prettier的,而且了解到了如何通过 babel 的 parseSync 解析 js代码。
Vite 是一个用于现代 JavaScript 应用程序的快速、轻量级的构建工具,其设计目的是易于使用和适用于大型项目。Vite-pretty-lint 是一个插件,可以在基于 Vite 的项目中安装和配置,以便在编写代码时能够自动对代码进行格式化和检查代码。这可以帮助开发人员在开发过程的早期捕获格式化和链接错误,并确保代码库遵循一致的样式。,学习目标:,资源:,创建一个vite项目:,进入项目文件夹下,安装 Vite-pretty-lint:,执行上面命令后,会提示选择项目类型和你使用的那种包管理器,如图: <img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/9039a03050b04630bbfd7c1ce596e3a1~tplv-k3u1fbpfcp-watermark.image?" alt="" width="70%" />,施加魔法中,稍等片刻,它给你的项目自动添加上eslint与prettier的配置,懒人福音啊。,<img src="https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/68a1c56111224dcaa3832986665151d0~tplv-k3u1fbpfcp-watermark.image?" alt="" width="40%" />,可以发现,执行
npm init Vite-pretty-lint 我们的项目主要发生了如下的变化:,其实,实现上述功能所用到的方法这这篇文章
源码共读 - 构建脚手架(2K字长文) 中都有出现,为了加深印象,我们再来复习一遍。,找到脚本的入口文件。如图:,<img src="https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/1e6858c15aa14a43a459e7a3d1d0b070~tplv-k3u1fbpfcp-watermark.image?" alt="" width="40%" />,源码:,询问项目类型,之后根据用户选择的项目类型复制对应的模板文件,询问包管理器类型,用于安装依赖。,这里交互式命令提示工具使用的是 enquirer 包。,做完询问工作,使用exec执行命令安装依赖,然后使用
fs.writeFileSync 复制文件。,parseSync 方法用于解析一串 JavaScript 代码并返回代码的抽象语法树(AST)表示。AST 是一个树状结构,表示代码的结构,它可以用来以各种方式分析或修改代码。,ParseSync 方法有两个参数:,通过本次课程,不仅学习到了
Vite-pretty-lint 是如何自动配置eslint与prettier的,而且了解到了如何通过 babel 的 parseSync 解析 js代码。,parseSync 方法用于解析一串 JavaScript 代码并返回代码的抽象语法树(AST)表示。AST 是一个树状结构,表示代码的结构,它可以用来以各种方式分析或修改代码。,
Vite 是一个用于现代 JavaScript 应用程序的快速、轻量级的构建工具,其设计目的是易于使用和适用于大型项目。Vite-pretty-lint 是一个插件,可以在基于 Vite 的项目中安装和配置,以便在编写代码时能够自动对代码进行格式化和检查代码。这可以帮助开发人员在开发过程的早期捕获格式化和链接错误,并确保代码库遵循一致的样式。
学习目标:
- 如何为 vite 项目自动添加 eslint 和 prettier
- 它的原理是什么
资源:
- 源码地址:vite-pretty-lint
创建一个vite项目:
npm init vite
进入项目文件夹下,安装 Vite-pretty-lint:
npm init Vite-pretty-lint
执行上面命令后,会提示选择项目类型和你使用的那种包管理器,如图: <img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/9039a03050b04630bbfd7c1ce596e3a1~tplv-k3u1fbpfcp-watermark.image?" alt="" width="70%" />
施加魔法中,稍等片刻,它给你的项目自动添加上eslint与prettier的配置,懒人福音啊。
<img src="https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/68a1c56111224dcaa3832986665151d0~tplv-k3u1fbpfcp-watermark.image?" alt="" width="40%" />
可以发现,执行 npm init Vite-pretty-lint 我们的项目主要发生了如下的变化:
- 自动生成了配置文件
- 添加了依赖
其实,实现上述功能所用到的方法这这篇文章 源码共读 - 构建脚手架(2K字长文) 中都有出现,为了加深印象,我们再来复习一遍。
找到脚本的入口文件。如图:
<img src="https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/1e6858c15aa14a43a459e7a3d1d0b070~tplv-k3u1fbpfcp-watermark.image?" alt="" width="40%" />
源码:
try {
const answers = await askForProjectType();
projectType = answers.projectType;
packageManager = answers.packageManager;
} catch (error) {
console.log(chalk.blue('\n Goodbye!'));
return;
}
const { packages, eslintOverrides } = await import(
`./templates/${projectType}.js`
);
询问项目类型,之后根据用户选择的项目类型复制对应的模板文件,询问包管理器类型,用于安装依赖。
// util.js
export function askForProjectType() {
return enquirer.prompt([
{
type: 'select',
name: 'projectType',
message: 'What type of project do you have?',
choices: getOptions(),
},
{
type: 'select',
name: 'packageManager',
message: 'What package manager do you use?',
choices: ['npm', 'yarn', 'pnpm'],
},
]);
}
这里交互式命令提示工具使用的是 enquirer 包。
exec(`${commandMap[packageManager]}`, { cwd: projectDirectory }, (error) => {
if (error) {
spinner.error({
text: chalk.bold.red('Failed to install packages!'),
mark: '',
});
console.error(error);
return;
}
fs.writeFileSync(eslintFile, JSON.stringify(eslint, null, 2));
fs.writeFileSync(prettierFile, JSON.stringify(prettierConfig, null, 2));
fs.writeFileSync(eslintIgnoreFile, eslintIgnore.join('\n'));
fs.writeFileSync(viteFile, viteConfig);
spinner.success({ text: chalk.bold.green('All done! '), mark: '' });
console.log(
chalk.bold.cyan('\n Reload your editor to activate the settings!')
);
});
exec(`${commandMap[packageManager]}`, { cwd: projectDirectory }, (error) => {
if (error) {
spinner.error({
text: chalk.bold.red('Failed to install packages!'),
mark: '',
});
console.error(error);
return;
}
fs.writeFileSync(eslintFile, JSON.stringify(eslint, null, 2));
fs.writeFileSync(prettierFile, JSON.stringify(prettierConfig, null, 2));
fs.writeFileSync(eslintIgnoreFile, eslintIgnore.join('\n'));
fs.writeFileSync(viteFile, viteConfig);
spinner.success({ text: chalk.bold.green('All done! '), mark: '' });
console.log(
chalk.bold.cyan('\n Reload your editor to activate the settings!')
);
});
做完询问工作,使用exec执行命令安装依赖,然后使用 fs.writeFileSync 复制文件。
export function viteEslint(code) {
// 解析配置为抽象语法树
const ast = babel.parseSync(code, {
sourceType: 'module',
comments: false,
});
const { program } = ast;
// 将import 声明映射为一个列表
const importList = program.body
.filter((body) => {
return body.type === 'ImportDeclaration';
})
.map((body) => {
delete body.trailingComments;
return body;
});
// 找到 vite-plugin-eslint 下写入代码
if (importList.find((body) => body.source.value === 'vite-plugin-eslint')) {
return code;
}
const nonImportList = program.body.filter((body) => {
return body.type !== 'ImportDeclaration';
});
const exportStatement = program.body.find(
(body) => body.type === 'ExportDefaultDeclaration'
);
if (exportStatement.declaration.type === 'CallExpression') {
const [argument] = exportStatement.declaration.arguments;
if (argument.type === 'ObjectExpression') {
const plugin = argument.properties.find(
({ key }) => key.name === 'plugins'
);
if (plugin) {
plugin.value.elements.push(eslintPluginCall);
}
}
}
importList.push(eslintImport);
importList.push(blankLine);
program.body = importList.concat(nonImportList);
ast.program = program;
return babel.transformFromAstSync(ast, code, { sourceType: 'module' }).code;
}
export function viteEslint(code) {
// 解析配置为抽象语法树
const ast = babel.parseSync(code, {
sourceType: 'module',
comments: false,
});
const { program } = ast;
// 将import 声明映射为一个列表
const importList = program.body
.filter((body) => {
return body.type === 'ImportDeclaration';
})
.map((body) => {
delete body.trailingComments;
return body;
});
// 找到 vite-plugin-eslint 下写入代码
if (importList.find((body) => body.source.value === 'vite-plugin-eslint')) {
return code;
}
const nonImportList = program.body.filter((body) => {
return body.type !== 'ImportDeclaration';
});
const exportStatement = program.body.find(
(body) => body.type === 'ExportDefaultDeclaration'
);
if (exportStatement.declaration.type === 'CallExpression') {
const [argument] = exportStatement.declaration.arguments;
if (argument.type === 'ObjectExpression') {
const plugin = argument.properties.find(
({ key }) => key.name === 'plugins'
);
if (plugin) {
plugin.value.elements.push(eslintPluginCall);
}
}
}
importList.push(eslintImport);
importList.push(blankLine);
program.body = importList.concat(nonImportList);
ast.program = program;
return babel.transformFromAstSync(ast, code, { sourceType: 'module' }).code;
}
parseSync 方法用于解析一串 JavaScript 代码并返回代码的抽象语法树(AST)表示。AST 是一个树状结构,表示代码的结构,它可以用来以各种方式分析或修改代码。
ParseSync 方法有两个参数:
- Code: 包含要解析的 JavaScript 代码的字符串。
- Options: 包含解析器配置选项的可选对象。
通过本次课程,不仅学习到了 Vite-pretty-lint 是如何自动配置eslint与prettier的,而且了解到了如何通过 babel 的 parseSync 解析 js代码。