monaco-editor-nls-adapter 1.0.1 → 2.0.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/transform.js CHANGED
@@ -1,37 +1,73 @@
1
- const MONACO_ESM_ROOT = 'node_modules/monaco-editor/esm/'
1
+ const MagicString = require('magic-string')
2
+
3
+ let CACHED_MONACO_ROOT = null
2
4
 
3
5
  /**
4
6
  * 转换 Monaco Editor 源代码以注入本地化路径
5
7
  * @param {string} source 源代码内容
6
8
  * @param {string} id 文件路径 (resourcePath 或 vite id)
7
- * @returns {string} 转换后的代码
9
+ * @param {Object} options 配置项
10
+ * @param {string} options.monacoPath 匹配 Monaco Editor 的路径片段,默认为 'monaco-editor/esm'
11
+ * @returns {Object|string} 转换后的对象 { code, map } 或原始字符串
8
12
  */
9
- function transform(source, id) {
13
+ function transform(source, id, options = {}) {
10
14
  // 统一路径分隔符
11
15
  const resourcePath = id.replace(/\\/g, '/')
16
+ let monacoRoot = options.monacoPath || 'monaco-editor/esm'
17
+
18
+ // 4. 自动路径探测增强:如果是默认路径且在 node_modules 中,尝试自动定位物理路径
19
+ if (monacoRoot === 'monaco-editor/esm' && !CACHED_MONACO_ROOT) {
20
+ try {
21
+ // 尝试自动定位 monaco-editor 的安装目录 (适配 pnpm, npm, yarn)
22
+ const pkgPath = require.resolve('monaco-editor/package.json', { paths: [process.cwd()] })
23
+ CACHED_MONACO_ROOT = pkgPath.replace(/\\/g, '/').replace('package.json', 'esm')
24
+ } catch (e) {
25
+ // 容错:如果无法解析,则暂时保持原样
26
+ }
27
+ }
28
+
29
+ // 优先匹配物理路径,否则回退到特征字符串匹配
30
+ const matchPath = CACHED_MONACO_ROOT || monacoRoot
12
31
 
13
- if (resourcePath.includes(MONACO_ESM_ROOT)) {
14
- // 1. 计算 Monaco 模块路径 (例如 vs/editor/common/editorContextKeys)
15
- const startIndex = resourcePath.indexOf(MONACO_ESM_ROOT) + MONACO_ESM_ROOT.length
16
- const modulePath = resourcePath.substring(startIndex).replace('.js', '')
32
+ if (resourcePath.includes(matchPath)) {
33
+ // 计算模块路径 (相对于 esm 目录)
34
+ const lastIndex = resourcePath.lastIndexOf(matchPath)
35
+ const startIndex = lastIndex + matchPath.length + 1
36
+ const modulePath = resourcePath.substring(startIndex).replace(/\.js$/, '')
17
37
 
18
- // 2. NLS 引用重定向到本包的代理 (proxy) 文件
38
+ if (!modulePath || modulePath.includes('node_modules')) return source
39
+
40
+ const s = new MagicString(source)
19
41
  const proxyPath = 'monaco-editor-nls-adapter/proxy'
20
-
21
- // 替换对 nls.js 的引用
22
- source = source.replace(/import\s+\*\s+as\s+nls\s+from\s+['"].*?\/nls\.js['"]/g, `import * as nls from '${proxyPath}'`)
23
- source = source.replace(/require\(['"].*?\/nls\.js['"]\)/g, `require('${proxyPath}')`)
42
+
43
+ // 2. 替换对 nls.js 的引用 (处理 import 和 require)
44
+ const nlsImportRegex = /(import\s+.*?\s+from\s+['"])(.*?\/nls\.js)(['"])/g
45
+ let match
46
+ while ((match = nlsImportRegex.exec(source)) !== null) {
47
+ s.overwrite(match.index + match[1].length, match.index + match[1].length + match[2].length, proxyPath)
48
+ }
49
+
50
+ const nlsRequireRegex = /(require\(['"])(.*?\/nls\.js)(['"]\))/g
51
+ while ((match = nlsRequireRegex.exec(source)) !== null) {
52
+ s.overwrite(match.index + match[1].length, match.index + match[1].length + match[2].length, proxyPath)
53
+ }
24
54
 
25
55
  // 3. 在 localize 和 localize2 调用中注入路径作为第一个参数
26
- // 注意:只替换调用,不改变原始代码逻辑
27
- source = source.replace(/nls\.localize\(/g, `nls.localize('${modulePath}', `)
28
- source = source.replace(/nls\.localize2\(/g, `nls.localize2('${modulePath}', `)
56
+ const localizeRegex = /nls\.localize(\d?)\(/g
57
+ while ((match = localizeRegex.exec(source)) !== null) {
58
+ // '(' 之后插入路径参数
59
+ s.appendLeft(match.index + match[0].length, `'${modulePath}', `)
60
+ }
61
+
62
+ return {
63
+ code: s.toString(),
64
+ map: s.generateMap({ hires: true, source: id, includeContent: true })
65
+ }
29
66
  }
30
67
 
31
68
  return source
32
69
  }
33
70
 
34
71
  module.exports = {
35
- transform,
36
- MONACO_ESM_ROOT
72
+ transform
37
73
  }
package/vite-plugin.js CHANGED
@@ -1,20 +1,32 @@
1
- const { transform, MONACO_ESM_ROOT } = require('./transform')
1
+ const { transform } = require('./transform')
2
2
 
3
3
  /**
4
4
  * Vite Plugin for Monaco Editor NLS Adapter
5
- * Supports both development and production builds.
5
+ * @param {Object} options 插件配置
6
+ * @param {string} options.monacoPath 匹配 Monaco Editor ESM 路径的特征字符串,默认为 'monaco-editor/esm'
6
7
  */
7
- function monacoNlsPlugin() {
8
+ function monacoNlsPlugin(options = {}) {
9
+ const monacoRoot = options.monacoPath || 'monaco-editor/esm'
10
+
8
11
  return {
9
12
  name: 'vite-plugin-monaco-nls-adapter',
10
- // 强制此插件在代码压缩和混淆之前执行
11
13
  enforce: 'pre',
12
14
  transform(code, id) {
13
- // 检查是否是 Monaco Editor 的 ESM 源码文件
14
- if (id.replace(/\\/g, '/').includes(MONACO_ESM_ROOT)) {
15
+ // 统一路径格式
16
+ const normalizedId = id.replace(/\\/g, '/')
17
+
18
+ // 快速过滤非目标文件
19
+ if (normalizedId.includes(monacoRoot) && normalizedId.endsWith('.js')) {
20
+ const result = transform(code, id, options)
21
+
22
+ // 如果 transform 返回的是对象 ({ code, map }),直接返回
23
+ if (result && typeof result === 'object') {
24
+ return result
25
+ }
26
+
27
+ // 否则返回原始代码
15
28
  return {
16
- code: transform(code, id),
17
- // 返回原始 map 或 null,由于是简单的正则匹配转换,不处理 SourceMap
29
+ code: result || code,
18
30
  map: null
19
31
  }
20
32
  }