自动替换前端node_modules源码

前言

  首先为什么要写这篇文章呢,因为我遇到了一个小问题,前几天在我的博客引入了评论的功能(Waline ),然后呢,就看了一下官方的配置文档, 里面有一些自定义的配置,需要在引入Waline 进行配置,然后发现我当前使用的Hexo主题并没有开放这些配置,也就是说我没办法修改Waline 的这些配置,然后就开始慢慢摸索,找到主题对于Waline 的配置的源代码, 然后呢,就出现了一个问题,因为是源码文件,都在node_modules文件夹下,所以修改只能在当前电脑生效,换个电脑是不会同步的…… 然后就有了这篇文章。

然后开始疯狂的搜索资料,终于找到了一个比较完美的解决方案

下面开始教程

这个教程的思路就是在打包之前执行一段代码,这段代码的作用就是自动替换node_modules对应的文件内容

首先在你的项目根目录创建两个文件夹change_modulesscript ,根据名字就能猜到第一个是存放你要替换的源码,第二个就是执行替换的脚本,

script 目录新建一个文件change_modules.js ,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

// 自动替换node_modules指定文件
const fs = require('fs')
const path = require('path')

// 将 change_modules 内的文件覆盖在node_modules中
const REAL_NODE_MODULES = path.resolve('./node_modules') // 旧node_modules
const MY_NODE_MODULES = path.resolve('./change_modules') // 新node_modules
copy(MY_NODE_MODULES, REAL_NODE_MODULES)

/**
*@param{string}需要复制的目录、文件
*@param{string}复制到指定的目录、文件
*@param{function}每次复制前,都会经过一次filterFn,若返回true,则复制。
*/
function copy(origin, target, filterFn = () => true) {
if (fs.statSync(origin).isDirectory()) {
if (!fs.existsSync(target)) {
fs.mkdirSync(target)
}
fs.readdirSync(origin).forEach(originName => {
const originFilePath = path.resolve(origin, originName)
const targetFilePath = path.resolve(target, originName)
copy(originFilePath, targetFilePath, filterFn)
})
} else if (filterFn(origin, target)) {
const fileName = path.basename(origin);
console.log("替换文件 " + fileName)
//执行替换
fs.copyFileSync(origin, target)
}
}

然后找到你项目的package.json ,找到类似下面代码的地方,就是你项目指定打包命令的地方,例如我这是hexo的打包命令

1
2
3
4
5
6
"scripts": {
"build": "node ./scripts/change_modules.js && hexo generate",
"clean": "hexo clean",
"deploy": "node ./scripts/change_modules.js && hexo deploy",
"server": "node ./scripts/change_modules.js && hexo server"
}

然后在你打包命令之前添加一段命令node ./scripts/change_modules.js ,用来执行你创建的脚本文件

然后最重要的地方来了,复制你想修改的node_modules 里面的源码文件到change_modules
注意保证路径相同!注意保证路径相同!注意保证路径相同!重要的事情说三遍

到这里差不多就结束了,然后当你再次执行打包命令时,就会看到如下的输出:

1
替换文件 ********

看到这个说明就是成功了

最后呢,在附上我修改的Waline 的一些配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
const locale = {
nick: '你的专属昵称',
nickError: '昵称太短啦!至少得有3个字符才能算数哦!',
mail: '你的电子小信箱',
mailError: '哎呀,这不是一个合格的邮箱地址哦,请再检查一遍!',
link: '你有个酷酷的网址吗?',
optional: '这个嘛,想填就填,不填也行!',
placeholder: '吐槽一下?',
sofa: '来,坐沙发上,发表你的评论吧!',
submit: '一键发送,让世界听到你的声音!',
like: '点个赞,让TA知道你的心意!',
cancelLike: '哎呀,不小心点错了,取消赞!',
reply: '回复TA,开启一场对话吧!',
cancelReply: '等等,我话还没说完,取消回复!',
comment: '来,说说你的看法,让评论区热闹起来!',
refresh: '刷新一下,看看有啥新动态!',
more: '哇塞,还有更多精彩内容等你来加载!',
preview: '先睹为快,预览一下你的大作吧!',
emoji: '来,加点表情,让你的评论更生动!',
uploadImage: '上传你的美照,让大家一起欣赏!',
seconds: '刚刚才发的,新鲜出炉!',
minutes: '几分钟前,还热乎着呢!',
hours: '几小时前,热度还在哦!',
days: '几天前,但依旧值得一看!',
now: '哇塞,刚刚发的,快抢沙发!',
uploading: '稍等片刻,你的图片正在飞奔而来!',
login: '登录一下,解锁更多功能!',
logout: '拜拜了您嘞,下次再见!',
admin: '博主大人在此,谁敢造次!',
sticky: '置顶一下,让更多人看到你的精彩内容!',
word: '字',
wordHint: '评论字数要在0到1字之间哦!\n现在你已经写了$2个字了,加油!',
anonymous: '神秘人出没,猜猜是谁?',
level0: '潜水员,深藏不露!',
level1: '冒泡小能手,偶尔露个头!',
level2: '吐槽大师,一针见血!',
level3: '活跃分子,无处不在!',
level4: '话痨达人,说个不停!',
level5: '传说级大神,膜拜一下!',
gif: '动态表情包,让你的评论更有趣!',
gifSearchPlaceholder: '快来搜索你喜欢的表情包,让评论更生动!',
profile: '看看我的个人资料,了解一下我吧!',
approved: '审核通过,可以展示啦!',
waiting: '正在等待审核,别急哦!',
spam: '垃圾内容,走开走开!',
unsticky: '换个位置看看!',
oldest: '看看最早的评论!',
latest: '看看最新的动态!',
hottest: '看看哪条评论最火!',
reactionTitle: '快来对这篇文章发表你的看法吧,让博主知道你的想法!😜'
};


const waline = Waline.init(Object.assign({
//…………
reaction: true,
locale
}

这个配置的效果你可以到下面的评论区看看😎