Open Symbolk opened 3 years ago
目前写了一个配置,但是貌似TreeSitter会有问题,你们碰到过或知道如何解决吗? @Shigma @TsukimiRini
试试看这个?
import TreeSitter from 'tree-sitter'
试试看这个?
import TreeSitter from 'tree-sitter'
提示需要在tsconfig中设置"esModuleInterop": true,
但设置之后会在编译test/index.ts(使用yo初始化项目时自动产生的test suite)时出现错误:
移除index.ts之后可以正常运行,vsce package不再警告,但独立安装后仍有 Error: Cannot find module './build/Release/tree_sitter_runtime_binding'错误
刚刚重新看了一下 dts 文件,之前我说的有误。我先说一下 ts 中模块导出和引入的三种方法:
export { xxx }
导出(export const / function / class / namespace / type xxx
同理),此时应该使用 import { xxx } from
导入。export default xxx
导出,此时应该使用 import xxx from
导入。export = xxx
导出(这种写法是 ts 为了 node 兼容性引入的,非 es 标准语法),此时有三种解决方案:
import xxx from
导入import { xxx } from
导入,同时配置 esModuleInterop
import xxx = require()
导入(这种写法同样也非 es 标准语法,导入的模块同样会有类型标注不用担心)然后 tree-sitter 和 mocha 的类型定义都是 export = xxx
形式的,所以还是应该直接 import xxx from
(同时也不需要配置 esModuleInterop
)。
那么为啥 esbuid 会报 warning 呢?这里牵扯到 esmodule 标准执行的问题。
cjs 在 esm 标准被推广之前就已经大行其道,在 cjs 中模块的导出无非就是一个对象,其他模块 require 这个模块的时候,返回的就是这个对象本身,因此这个对象的所有属性都是可以被修改的。
// 1.js
module.exports = { foo: 'bar' }
// 2.js
const ns = require('1.js')
ns.foo = 'baz'
// 3.js
const ns = require('1.js')
require('2.js')
console.log(ns.foo) // baz
然而根据 esm 规范:
9.4.6.8 [[Set]] ( P, V, Receiver )
When the [[Set]] internal method of a module namespace exotic object O is called with property key P, value V, and ECMAScript language value Receiver, the following steps are taken:
Return false.
因此,将上面的写法换成 esm,得到的结果就会不同:
// 1.js
export const foo = 'bar'
// 2.js
import * as ns from '1.js'
ns.foo = 'baz'
// 3.js
import * as ns from '1.js'
import '2.js'
console.log(ns.foo) // bar
回到上面列举的三种导出方法,为什么 ts 要创造一种有别于 esm 的新语法呢?这是因为 cjs 没有 export default
,在 esModuleInterop
的帮助下,ts 用户可以使用任何一种方式导入上面的文件,非常方便:
// 源文件 1.ts
const ns = { foo: 'bar' }
export = ns
// 编译后的 1.d.ts
declare ns: { foo: string }
export = ns
// 编译后的 1.js,简化了各种 helper
const ns = { foo: 'bar' }
Object.defineProperty(ns, 'esModule', { value: true })
Object.defineProperty(ns, 'default', { value: ns })
module.exports = ns
// some-file.ts
import { foo } from '1.js'
import ns from '1.js'
这对于 ts 自身的生态没有问题,但是当有了 esbuild 就不一样了。esbuild 作者坚持使用符合标准的实现,导致所有 import xxx from
都会被打包一层 helper,将其中的所有属性都变成 getter,这会导致许多库都没法正常导入。在这种情况下使用上文中提及的第三种方法导入才是最稳妥的选择。
如果要在测试环境也使用 esbuild,同样需要把 mocha 的导入也改掉。
目标:使用esbuild压缩与发布somanyconflicts release版本。
分支:build
参考:https://code.visualstudio.com/api/working-with-extensions/bundling-extension