总结
根据路线图上的重点去进行有针对性的学习,在学习过程中,学会写笔记,做总结。
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
这里分享一些前端学习笔记:
-
html5 / css3 学习笔记
-
JavaScript 学习笔记
-
Vue 学习笔记
-
项目在main.js中有全局引入业务组件(还有directives filters),但是业务组件不一定是在每个页面都使用
-
项目在main.js中有全局引入常量(还有utils)
这两个点在很多项目都会有,常规的思路是我们手动的一个组件一个组件的搜,然后修改。可是对于文件很多的老系统来说不太现实,需要大量的人去做这种事情。
思路
- 将所有的业务组件遍历出来生成一个
Map<componentName,componentPath>
- 使用
glob
库拿到所有的vue
js
文件 - 定义2个方法
- 使用
vue-template-compiler
解析模板 看一下当前页面是否使用公共业务组件,有的话放到一个数组内 - 使用
@babel/parser
解析js
生成ast
- 解析 ast 看看是否引入 并且在components内注册,如果没有的话引入,并且注册
- 使用
动手
首先我们把所需要的包安装一下,我们先操作单个文件,
pnpm i @babel/parser @babel/generator @babel/traverse @babel/types vue-template-compiler glob
复制代码
生成 Map<componentName,componentPath>
我们项目的业务组件还比较规范(如果实在不规范,其实手动维护一下这个Map也工作量不大),src/common/components有2个文件夹 basic 是基础组件,business里面是基于基础组件生成的业务组件,当然代码库内的代码都是随便写的,只是为了展示如何做自动加载组件
这一部分代码比较简单,引入fs,然后遍历文件夹就可以了
/**
*
* @param {string} p 路径
*/
function resolve (p) {
return path.resolve(__dirname, '..', p)
}
// 所有组件的组件的 名称和路径映射
const allComponentMaps = fs.readdirSync(resolve('src/common/components/basic')).reduce((prev, cur) => {
// 我们项目不存在直接放外面的组件
if (!cur.includes('.')) {
prev[cur] = `@/common/components/basic/${cur}`
}
return prev
}, {})
fs.readdirSync(resolve('src/common/components/business')).reduce((prev, cur) => {
// 我们项目不存在直接放外面的组件
if (!cur.includes('.')) {
prev[cur] = `@/common/components/business/${cur}`
}
return prev
}, allComponentMaps)
console.log(allComponentMaps)
复制代码
用nodemon运行这个js 可以得出如下结果
解析vue文件
首先准备一个app.vue内容如下
<template>
<div id="app">
<div id="nav">
<s-input />
<s-file />
</div>
<router-view/>
</div>
</template>
<script>
export default {
data () {
return {
}
},
components: {
}
}
</script>
复制代码
首先通过fs模块得到源码的内容 content
// 目标文件
const targetFile = path.resolve(__dirname, './App.vue')
// 得到文件内容
const content = fs.readFileSync(targetFile).toString()
复制代码
然后编写一个方法解析html模板
/**
*
* @param {t.node} node
* @param {Set} result
*/
function parseHTML (node, result = new Set()) {
if (allComponentList.some(item => item === node.tag)) {
result.add(node.tag)
} else {
(node.children || []).forEach(element => {
parseHTML(element, result)
})
}
return result
}
const result = parseHTML(compiler.compile(content).ast)
复制代码
可以看到控制台输出
得到当前文件使用了哪些业务组件后,接下来就是解析js,然后动态的import进去并注册就好了
借助一个网站我们可以知道 直接import A from ‘b'
中的A是 ImportDefaultSpecifier
类型
通过看ast。我们可以得知一条import 语句是ImportDeclaration类型的,所以借助@babel/types
可以生成ImportDeclaration,
如何使用@babel/types 生成语句
我们使用 t 代表@babel/types
一个import 语句的type是ImportDeclaration 那么就调用 t.importDeclaration方法 看api文档可以得知 t.importDeclaration 方法第一个入参就是ImportDefaultSpecifier类型 ImportDefaultSpecifier 可以借助t.importDefaultSpecifier方法生成
最后
推荐一些系统学习的途径和方法。
每个Web开发人员必备,很权威很齐全的Web开发文档。作为学习辞典使用,可以查询到每个概念、方法、属性的详细解释,注意使用英文关键字搜索。里面的一些 HTML,CSS,HTTP 技术教程也相当不错。
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
HTML 和 CSS: