@ray-js/ray 1.3.0-beta.2-beta-2 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@ray-js/ray",
|
3
|
-
"version": "1.3.0
|
3
|
+
"version": "1.3.0",
|
4
4
|
"description": "ray",
|
5
5
|
"keywords": [
|
6
6
|
"ray"
|
@@ -15,18 +15,20 @@
|
|
15
15
|
"unified.mini.js",
|
16
16
|
"main",
|
17
17
|
"macro.js",
|
18
|
-
"macro.d.ts"
|
18
|
+
"macro.d.ts",
|
19
|
+
"plugins"
|
19
20
|
],
|
20
21
|
"publishConfig": {
|
21
22
|
"access": "public",
|
22
23
|
"registry": "https://registry.npmjs.org"
|
23
24
|
},
|
24
25
|
"dependencies": {
|
25
|
-
"@ray-core/
|
26
|
-
"@ray-
|
27
|
-
"@ray-js/
|
28
|
-
"@ray-js/
|
29
|
-
"@ray-js/
|
26
|
+
"@ray-core/html2mini-plugin": "0.0.7",
|
27
|
+
"@ray-core/macro": "^0.3.0",
|
28
|
+
"@ray-js/api": "^1.3.0",
|
29
|
+
"@ray-js/capability": "^1.3.0",
|
30
|
+
"@ray-js/components": "^1.3.0",
|
31
|
+
"@ray-js/framework": "^1.3.0"
|
30
32
|
},
|
31
33
|
"maintainers": [
|
32
34
|
{
|
@@ -34,6 +36,6 @@
|
|
34
36
|
"ezmail": "tuyafe@tuya.com"
|
35
37
|
}
|
36
38
|
],
|
37
|
-
"gitHead": "
|
39
|
+
"gitHead": "f7f96c375a429a2fa94452b0a9af3f841572921a",
|
38
40
|
"repository": {}
|
39
41
|
}
|
@@ -0,0 +1,164 @@
|
|
1
|
+
/**
|
2
|
+
* i18n plugin
|
3
|
+
*
|
4
|
+
* 用于将语言包从项目 src/i18n 或 src/locales 目录 或 node_modules/@ray-js/i18n 目录
|
5
|
+
* 且该目录下的以 {strings|index}.{js|json|ts} 结尾的文件转换为 strings.json
|
6
|
+
* 并 strings.json 提取到构建目录的 i18n 目录中
|
7
|
+
*
|
8
|
+
*/
|
9
|
+
|
10
|
+
const pluginName = 'i18n-plugin'
|
11
|
+
const path = require('path')
|
12
|
+
const fs = require('fs-extra')
|
13
|
+
const { requireJSFile } = require('@ray-js/shared')
|
14
|
+
|
15
|
+
const exts = ['json', 'js', 'ts']
|
16
|
+
const names = exts.map((ext) => `strings.${ext}`).concat(exts.map((ext) => `index.${ext}`))
|
17
|
+
|
18
|
+
class I18nPlugin {
|
19
|
+
constructor({ i18n, locales }) {
|
20
|
+
this.i18n = i18n
|
21
|
+
this.locales = locales
|
22
|
+
}
|
23
|
+
|
24
|
+
apply(compiler) {
|
25
|
+
compiler.hooks.assetEmitted.tap(pluginName, () => {
|
26
|
+
this.i18n.i18nPkgBuilder()
|
27
|
+
this.locales.i18nPkgBuilder()
|
28
|
+
})
|
29
|
+
}
|
30
|
+
}
|
31
|
+
|
32
|
+
const throttle = function (fn, timeout) {
|
33
|
+
let id
|
34
|
+
return function (...args) {
|
35
|
+
clearTimeout(id)
|
36
|
+
id = setTimeout(() => fn(...args), timeout)
|
37
|
+
}
|
38
|
+
}
|
39
|
+
|
40
|
+
const i18nPkgBuilderCreator = function (root, outputFile) {
|
41
|
+
const filenames = names.map((item) => path.join(root, item))
|
42
|
+
let cache
|
43
|
+
const handle = (name) => {
|
44
|
+
if (!fs.existsSync(root)) {
|
45
|
+
return
|
46
|
+
}
|
47
|
+
|
48
|
+
let filename
|
49
|
+
// 因 fs.watch 无法区别文件删除和文件重命名
|
50
|
+
// 所以只能通过判断文件是否存在
|
51
|
+
|
52
|
+
// 更新时name不为空
|
53
|
+
if (name) {
|
54
|
+
filename = path.join(root, name)
|
55
|
+
// 文件不存在,可能是删除操作
|
56
|
+
if (!fs.existsSync(filename)) {
|
57
|
+
delete require.cache[filename]
|
58
|
+
cache && (cache = null)
|
59
|
+
return
|
60
|
+
}
|
61
|
+
}
|
62
|
+
|
63
|
+
const files = filenames.filter((item) => fs.existsSync(item))
|
64
|
+
|
65
|
+
if (files.length > 1) {
|
66
|
+
console.warn(`${pluginName}: Has more than one file: ${files.join('\n')}`)
|
67
|
+
console.warn(`${pluginName}: Will use first file: ${files[0]}`)
|
68
|
+
}
|
69
|
+
|
70
|
+
if (!filename) {
|
71
|
+
// 初始化时filename为空
|
72
|
+
if (files.length) {
|
73
|
+
filename = files[0] // 取第一个文件
|
74
|
+
} else {
|
75
|
+
return
|
76
|
+
}
|
77
|
+
}
|
78
|
+
|
79
|
+
// 记住上一次使用的语言包文件
|
80
|
+
if ((!cache || cache !== filename) && filenames.includes(filename)) {
|
81
|
+
cache = filename
|
82
|
+
}
|
83
|
+
delete require.cache[filename]
|
84
|
+
const data = requireJSFile(cache)
|
85
|
+
|
86
|
+
if (data) {
|
87
|
+
fs.outputFile(outputFile, JSON.stringify(data, null, 2), 'utf-8')
|
88
|
+
}
|
89
|
+
}
|
90
|
+
handle.clear = function () {
|
91
|
+
cache = null
|
92
|
+
}
|
93
|
+
return handle
|
94
|
+
}
|
95
|
+
|
96
|
+
const i18nHandleCreator = (root, langDirName, outputFile) => {
|
97
|
+
let i18nDirWatcher
|
98
|
+
const i18nDirName = path.join(root, langDirName)
|
99
|
+
const i18nPkgBuilder = i18nPkgBuilderCreator(i18nDirName, outputFile)
|
100
|
+
const throttledI18nPkgBuilder = throttle(i18nPkgBuilder, 50)
|
101
|
+
|
102
|
+
const i18nDirHandle = (name) => {
|
103
|
+
if (!i18nDirWatcher && name !== langDirName) {
|
104
|
+
return
|
105
|
+
}
|
106
|
+
|
107
|
+
const exist = fs.existsSync(i18nDirName)
|
108
|
+
|
109
|
+
// 说明i18n目录被删除了,关闭监听
|
110
|
+
if (i18nDirWatcher && !exist) {
|
111
|
+
i18nDirWatcher.close()
|
112
|
+
i18nDirWatcher = null
|
113
|
+
i18nPkgBuilder.clear()
|
114
|
+
return
|
115
|
+
}
|
116
|
+
// i18n 目录删除后又创建了,需要重新监听之
|
117
|
+
if (!i18nDirWatcher && exist) {
|
118
|
+
i18nDirWatcher = fs.watch(i18nDirName, (_, name) => throttledI18nPkgBuilder(name))
|
119
|
+
}
|
120
|
+
}
|
121
|
+
|
122
|
+
const throttledI18nDirHandle = throttle(i18nDirHandle, 50)
|
123
|
+
|
124
|
+
return {
|
125
|
+
i18nWatcherHandle: function () {
|
126
|
+
// 初始化时判断是否存在 i18n 目录,若存在则监听之
|
127
|
+
const exist = fs.existsSync(i18nDirName)
|
128
|
+
if (exist) {
|
129
|
+
i18nDirWatcher = fs.watch(i18nDirName, { recursive: true }, (_, name) =>
|
130
|
+
throttledI18nPkgBuilder(name)
|
131
|
+
)
|
132
|
+
}
|
133
|
+
// 监听 root(即src目录),用于动态判断 i18n 目录是否存在,若存在则监听之
|
134
|
+
fs.watch(root, (_, name) => throttledI18nDirHandle(name))
|
135
|
+
},
|
136
|
+
i18nPkgBuilder,
|
137
|
+
}
|
138
|
+
}
|
139
|
+
|
140
|
+
module.exports = (ctx) => {
|
141
|
+
const { options } = ctx
|
142
|
+
const { cwd, source, output, watch } = options
|
143
|
+
const i18nDistPath = path.join(output, 'i18n', 'strings.json')
|
144
|
+
const srcDir = path.join(cwd, source)
|
145
|
+
const i18n = i18nHandleCreator(srcDir, 'i18n', i18nDistPath)
|
146
|
+
const locales = i18nHandleCreator(srcDir, 'locales', i18nDistPath)
|
147
|
+
|
148
|
+
return {
|
149
|
+
name: pluginName,
|
150
|
+
setup() {
|
151
|
+
if (watch) {
|
152
|
+
i18n.i18nPkgBuilder()
|
153
|
+
locales.i18nPkgBuilder()
|
154
|
+
i18n.i18nWatcherHandle()
|
155
|
+
locales.i18nWatcherHandle()
|
156
|
+
}
|
157
|
+
},
|
158
|
+
configWebpack({ config }) {
|
159
|
+
if (!watch) {
|
160
|
+
config.plugin(pluginName).use(I18nPlugin, [{ i18n, locales }])
|
161
|
+
}
|
162
|
+
},
|
163
|
+
}
|
164
|
+
}
|