按 es6 的规范 import * as obj from "xxx" 会将 "xxx" 中所有 export 导出的内容组合成一个对象返回。如果都使用 es6 的规范,这个是很明确的。
但是现在问题来了,moment 不是一个符合 es6 规范的库。
不管是 AMD、CMD 还是 CommonJS,都是通过 module.exports 导出,AMD 和 CMD 还可以通过工厂函数 return 来导出。不过是 module.exports = ... 还是 function factory() { return ... } 哪种方式,都对默认提供的 module.exports 对象进行了替换,它可以是任意 JS 数据类型,函数就是一种很常用的数据类型。
TypeScript 对 ES6 export 的转译,是将所有 export 的东西,都作为 exports,即 module.exports 的属性,比如
// test.ts
export function hello() {}
const a = 0
export default a
用 tsc 按 AMD 模块转译
tsc test.ts --module AMD
得到
define(["require", "exports"], function (require, exports) {
"use strict"
function hello() { }
exports.hello = hello
var a = 0
exports.__esModule = true
exports["default"] = a
})
所以 TypeScript 对 import * as x from "./test.js" 的转译直接转译成
var x = require("./test")
是可以理解的。
Babel 也类似,同样的 es6 代码转译出来是
// by babel
"use strict"
Object.defineProperty(exports, "__esModule", {
value: true
})
exports.hello = hello
function hello() {}
var a = 0
exports.default = a
但是 Babel 想得比较复杂。既然不是 __esModule,说明不是 es6 定义的模块。那么按 es6 模块导出的方式,导入的肯定是一个对象,所以它就创建了一个新对象,把导出内容的所有属性拷贝过去,兼容 exports.xxx = xxx 或 module.exports 是个一般对象的情况。但万一 module.exports 不是个普通对象呢,假设它是当作 export default 导出的,所以最后加了句 newObj["default"] = ....
在这一点上其实我更倾向 Babel 的作法,但是这个转译没有标准(如果标准那么好定,NodeJS 早就用上 es6 的模块语法了)。
问题在于不管谁的作法,关键是你需要有一个统一的标准来兼容 TypeScript 和 Babel,那么要不试试
// .ts
import * as _moment from "./moment"
const moment = (_moment as any).default || _moment
(_moment as any).default 是为了 ts 编译不报错,|| _moment 是为了兼容有 default 和没有 default 的情况 (其实可以不做兼容处理,反正 Babel 处理过后一定会有 default)。
AS调用JS函数:ExternalInterface.call(JS中的函数名,参数一,参数二)//调用JS中的一个函数
以下AS代码:
import flash.external.ExternalInterface
例子:ExternalInterface.call('alert',‘hello world!’)//会弹出JS的提示框
JS调用AS函数:
ExternalInterface.addCallback(提供给JS调用的名称,调用的函数) //提供一个函数给JS调用
以下AS代码:
import flash.external.ExternalInterface
import mx.controls.Alert
public function asFunc(a:int,b:int):int
{
Alert.show(a+b)
}
ExternalInterface.addCallback("add",asFunc)
以下JS代码:
add(1,2)//调用的其实是AS中的asFunc方法 ,会在Flash中弹出提示框
通常,在项目中引用js库分两种情况:一种是通过npm install ${name} --save 安装在node_modules目录下,package.json中的dependencies会配置正式环境所依赖的库。另外一种就是直接将.js文件放在src目录下,通过相对路径的方式直接引用。对于第一种情况:例如:weixin-js-sdk,在项目路径下,cnpm install weixin-js-sdk --save, 安装成功以后,查看package.json下的dependencies会增加一行weixin-js-sdk的版本信息。在使用的时候导入 import * as WeiXin from 'weixin-js-sdk'对于第二种情况:通过相对路径引用一个.js文件,那么需要在tsconfig.json中的compilerOptions中配置"allowJs": true,然后在使用的时候直接import,例如:import * as Swiper from './lib/swiper/swiper.min.js'上面两种情况是在没有.d.ts声明文件的情况下对于有些三方库,例如bootstrap,jquery等许多常用的都有声明文件,直接导入就可以,例如jquery:1. cnpm install jquery --save 安装jquery依赖包到node_modules目录下2. npm install @types/jquery --save-dev 安装类型描述文件到node_modules目录下,只安装到开发环境3. 修改angular-cli.json文件,增加styles(引入css的路径)和scripts(引入js的路径) "scripts": ["../node_modules/jquery/dist/jquery.js"]4. 修改tsconfig.app.json文件,添加到types数组 "types": ["jquery"],然后就可以使用$语法了