TypeScript – Work with JavaScript Library
前言
JavaScript 早期是没有 Modular 和 Type (类型) 的. 随着这几年的普及, 几乎有维护的 Library 都有 Modular 和 Type 了.
但万一遇到没有 Modular 或者 Type 的 LIbrary 时, 要如何 import 和类型安全的调用它们呢?
这篇就是要讲讲这些麻烦事儿. 以前做 Angular 开发的时候也写过一篇相关的, 但那篇是基于 Angular 的, 这篇则底层一点, 只用了 TypeScript 和 SystemJS
请先阅读 , 本篇将基于它的基础作为例子.
搭环境
Follow 回这篇 的例子.
改一下它的 folder 结构. 全部放外面有点乱
index.html
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Documenttitle>
<script
src="https://cdn.jsdelivr.net/npm/systemjs@6.12.1/dist/s.min.js"
defer
>script>
<script
src="https://cdn.jsdelivr.net/npm/systemjs@6.12.1/dist/extras/named-register.min.js"
defer
>script>
<script
src="https://cdn.jsdelivr.net/npm/systemjs@6.12.1/dist/extras/amd.min.js"
defer
>script>
<script
src="https://cdn.jsdelivr.net/npm/systemjs@6.12.1/dist/extras/amd.min.js"
defer
>script>
<script type="systemjs-importmap">
{
"imports": {
"lodash": "https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js",
"jquery": "https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js"
}
}
script>
<script type="systemjs-module" src="../dist/bundle.js">script>
head>
<body>
<h1>Hello Worldh1>
body>
html>
index.ts
import { myModuleFunction } from './my-module';
myModuleFunction();
my-module.ts
import $ from 'jquery'; import _ from 'lodash'; export function myModuleFunction() { $('h1').css('color', 'blue'); _.forEach([1, 2, 3], (index) => $('body').append($(`${index}
`))); }
tsconfig.json
{ "compilerOptions": { "target": "es2016", "module": "System", "rootDir": "./src", "outFile": "./dist/bundle.js", "outDir": "./dist", "esModuleInterop": true, "forceConsistentCasingInFileNames": true, "strict": true, "skipLibCheck": true } }
Import Local JavaScript Library
默认配置下, TypeScript 不允许直接 import .js 文件.
local-js-library.js
export function localJsLibraryFunction(age) { return age; }
index.ts
直接报错
tsconfig.json
{ "compilerOptions": { "allowJs": true } }
开启 allowJs 就不会报错了
import { localJsLibraryFunction } from './local-js-library.js';
console.log('localJsLibraryFunction', localJsLibraryFunction(11));
虽然成功 import 到了, 但是会发现它有许多的 any 接口
如果想要有一点点类型, 但又不想搞 .d.ts 的话, 可以开启 checkJs
{ "compilerOptions": { "allowJs": true, "checkJs": true } }
这时会发现 local-js-module.js 报错了
它需要通过注释声明类型
/** * @param {number} age */ export function localJsLibraryFunction(age) { return age; }
这样 index.ts 就看的见类型了
注意坑
如果这时, 你把 import 删掉 > tsc > run LIve Server
你会发现跑不了, 虽然没有 import 了, 但是 bundle.js 依然会有 System.register local-js-library, 而这个就会让它坏掉了, 把这段注释掉就正常
没有去研究为什么, 我觉得用 allowJs 本身就不太顺风水, 强烈建议用 .d.ts 的方案.
Import no modular and no type JavaScript library
这种 Library 通常已经没用人维护了. 它的使用方式往往是叫你在 html 放