稀土掘金技术社区 02月27日
研发幸福论:从import顺序看代码的呼吸感
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

文章探讨了代码中import混乱的问题及解决方法,包括痛点分析、破局之道、适配指南、注意事项等,旨在提升开发体验和代码质量。

🎯指出import混乱的三大原罪:定位失焦、心智负担、协作灾难

💡提出破局之道:规范定义import层次,进行自动化校验,实现开发流闭环

📄介绍Vue生态适配指南及相关注意事项,如调整分组策略等

🎉阐述实践收益:新人上手时间减少,代码冲突率下降,释放心智资源

原创 海石 2025-02-26 08:31 重庆

点击关注公众号,“技术干货” 及时达!

前言

"啪!"刚接手新项目的你兴奋地双击打开项目文件,却被满屏的 import 语句当头一棒——React、antd、工具函数、业务组件像「被猫抓乱的毛线团纠缠在一起」

// 优化前的灾难现场import React, { useState } from "react";import ComponentC from "../components/ComponentC";import styles from "./index.module.scss";import testIcon from "@/images/test/testIcon.svg";import ComponentA from "../components/ComponentA";import { getMockDataList } from "@/service/testCenter";import { Spin } from "antd";import ComponentB from "../components/ComponentB";import { useEffect } from "react";

此刻的你,是否想起了被祖传代码支配的恐惧?

痛点直击:混乱import的三大原罪

    「定位失焦」:在antd组件和业务工具函数之间反复横跳,找依赖像玩"大家来找茬"

    「心智负担」:每次新增依赖都要纠结放在哪里,代码洁癖者的噩梦

    「协作灾难」:团队成员各写各的,PR评审变成import顺序辩论赛

破局之道:像整理衣橱般重构import

「第一性原理」:优秀的代码组织应该像宜家家具说明书——即使新手也能秒懂装配顺序

「技术方案三部曲」

    「规范定义」(立规矩)

// 理想中的import层次// 第一梯队:框架核心import React, { useState, useEffect } from 'react'
// 第二梯队:三方库import { Spin } from 'antd'import { useRouter } from 'react-router-dom'
// 第三梯队:项目模块import { getMockDataList } from '@/service/testCenter'import testIcon from "@/images/test/testIcon.svg";

// 第四梯队:同级组件import Topic from '../components/Topic'

    「自动化校验」(上手段)

请先安装 eslint-plugin-import 插件,

npm install eslint-plugin-import --save-dev

否则我们配置完 .eslintrc 文件后会发现,终端会报错:

1:1 error Definition for rule 'import/order' was not found

感谢评论区细心的掘友补充指正。


// .eslintrc 配置精髓 { // 在plugins数组的最后添加上“import”,告诉eslint要使用我们 // 刚刚安装好的eslint-plugin-import插件 plugins: ["react", "@typescript-eslint", "react-hooks", "import"], rules: { "import/order": [ "error", { "groups": [ "builtin", // Node内置 "external", // npm包 "internal", // 项目内部 "parent", // 父目录 "sibling", // 同级 "index" // 目录索引 ], "pathGroups": [ { "pattern": "react", "group": "external", "position": "before" }, { "pattern": "@/**", // 给别名路径特殊待遇 "group": "internal", "position": "before" } ], "newlines-between": "always", // 分组间空行 // 一定要手动修改下方的值,因为pathGroupsExcludedImportTypes // 的默认值是["builtin", "external", "object"], // 因此,假如我们不重新赋值,那么我们在pathGroups中 // 定义的有关react的配置,就会被排除(因为它属于external),设置的position: before // 并不会生效,我们会发现eslint还是提示我们应该将antd在react之前import // 所以再强调一遍,一定要修改pathGroupsExcludedImportTypes的值 "pathGroupsExcludedImportTypes": ["builtin"], "alphabetize": { // 字母表排序 "order": "asc", "caseInsensitive": true } } ] } }

    「开发流闭环」(提体验)

当我们完成前两步的时候,我们会发现,终端里的报错信息一下子就变多了,对于之前缺少管理的文件,我们得一个个手动修复,这实在是太累了。因此我们可以修改.vscode/settings.json文件

// 终极武器:保存即自动格式化{  "editor.codeActionsOnSave": {    "source.fixAll.eslint": true  },  "eslint.validate": ["javascript", "javascriptreact", "typescript", "typescriptreact"]}

这将在保存时自动应用 ESLint 的修复,包括 import 排序。

完成修改配置后,每次Cmd+ S自动获得:

// 如德芙般丝滑的import结构import React, { useEffect, useState } from 'react'
import { Spin } from 'antd'import { useRouter } from 'react-router-dom'
import { getMockDataList } from '@/service/testCenter'import testIcon from "@/images/test/testIcon.svg";
import styles from './index.module.scss'
import ComponentA from "../components/ComponentA";import ComponentB from "../components/ComponentB";import ComponentC from "../components/ComponentC";

Vue生态适配指南

对于<script setup>的魔法世界,只需微调分组策略:

"pathGroups": [  {    "pattern": "vue*",  // 捕获vue全家桶    "group": "external",    "position": "before"  }]

优化效果:

<script setup>import { ref } from 'vue'import { useStore } from 'vuex'
import { formatCurrency } from '@/libs/utils'
import ProductCard from './ProductCard.vue'</script>

❗️❗️❗️「注意事项」❗️❗️❗️

请注意,当你的vue项目是从vue官方文档通过执行

npm create vue@latest

命令创建的,那么你按照本篇博客的方式进行eslintrc.js的文件修改会出现问题,并不能达成期望的效果?。

出于篇幅考虑,在本篇博客中,我仅罗列我遇到的一些问题和解决方法,欢迎掘友在评论区分享其他的踩坑经验。

    「vite要求esm」:如果我们的eslintrc.js文件中存在module.exports的写法,那么在运行这个项目时会报错。由于脚手架项目在package.json中设置了"type": "module",这意味着所有.js文件都会被当作ES模块处理。而ESLint的配置文件如果使用.eslintrc.js,并且里面用了CommonJS的语法(比如module.exports),就会导致错误,因为ES模块中不能使用module.exports

 module.exports => export default 

    .eslintignore 文件已废弃」:在最新版的eslint中,不再建议用户通过创建.eslintignore 文件来忽略某些文件,而是期望「在 ESLint 配置中添加 ignores 字段」来实现对某些文件的忽略。


ignores: ["**/node_modules/**", "dist/**", "public/**"], // 替代 .eslintignore

    「ESLint在v8.23.0之后引入了Flat Config格式」:新的配置文件方式,使用eslint.config.js,而传统的.eslintrc.*文件不再被支持。


// eslint.config.js import eslintJs from "@eslint/js"; import importPlugin from "eslint-plugin-import"; import vuePlugin from "eslint-plugin-vue"; import globals from "globals";
export default [ { // 全局配置 languageOptions: { globals: { ...globals.browser, ...globals.node, AudioWorkletGlobalScope: true, }, parserOptions: { ecmaVersion: "latest", sourceType: "module", }, }, ignores: ["**/node_modules/**", "dist/**", "public/**"], // 替代 .eslintignore }, eslintJs.configs.recommended, // ESLint 推荐规则 ...vuePlugin.configs["flat/recommended"], // Vue3 推荐规则 { plugins: { import: importPlugin, }, // 自定义规则 rules: { "no-console": "warn",
"import/order": [ "error", { groups: [ "builtin", "external", "internal", ["sibling", "parent"], "index", "object", "type", ], pathGroups: [ { pattern: "vue*", group: "external", position: "before", }, { pattern: "@/hooks/**", group: "internal", position: "before", }, { pattern: "@/contexts/**", group: "internal", position: "before", }, { pattern: "@/components/**", group: "internal", position: "before", }, { pattern: "@/icons/**", group: "internal", position: "before", }, { pattern: "@/service/**", group: "internal", position: "before", }, { pattern: "@/images/**", group: "internal", position: "before", }, { pattern: "@/**", group: "internal", position: "before", }, { pattern: "./**", group: "sibling", position: "after", }, ], pathGroupsExcludedImportTypes: ["builtin"], alphabetize: { order: "asc", caseInsensitive: true, }, "newlines-between": "always", }, ], }, }, ];

    「请注意修改vite.config.js」:检查 vite.config.js 中的插件配置

  import { fileURLToPath, URL } from "node:url";
import vue from "@vitejs/plugin-vue"; import { defineConfig } from "vite"; import eslintPlugin from "vite-plugin-eslint";
// https://vitejs.dev/config/ export default defineConfig({ plugins: [ vue(), eslintPlugin({ // 关闭 LintOnStart 警告 lintOnStart: false, }), ], resolve: { alias: { "@": fileURLToPath(new URL("./src", import.meta.url)), }, }, });

    「确认是否安装好必要的依赖以及正确的依赖版本」

  "devDependencies": {        "@babel/eslint-parser": "^7.26.8",        "@eslint/js": "^9.20.0",        "@vitejs/plugin-vue": "^5.0.4",        "eslint": "^9.20.1",        "eslint-plugin-import": "^2.31.0",        "eslint-plugin-vue": "^9.32.0",        "globals": "^15.15.0",        "vite": "^5.2.8",        "vite-plugin-eslint": "^1.8.1"      },

这里的这个globals如果不安装最新版本很坑???,因为老版本存在一个错误的变量:老版本导出的AudioWorkletGlobalScope在内部是这么写的:"AudioWorkletGlobalScope ",没错,它居然在最后有个空格,这就导致我们运行项目,终端会报错❌,我真是服了.....

  10:14:23 [vite] Pre-transform error: Key "languageOptions": Key "globals": Global "AudioWorkletGlobalScope " has leading or trailing whitespace

研发幸福感公式

代码整洁度 × 自动化程度 = 开发愉悦指数

「实践收益」

「灵魂拷问」:当你的import顺序能像书架上的书籍分类般清晰,还会害怕需求变更吗?

结语

「技术启示录」:优秀的工程素养体现在对细节的极致追求。import顺序不仅是代码规范,更是研发团队的技术审美宣言。

点击关注公众号,“技术干货” 及时达!

阅读原文

跳转微信打开

Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

代码优化 import顺序 开发体验 Vue生态
相关文章