我正在尝试用typescript创建一个带有导出的js包,我可以直接从内联脚本调用它,但我似乎无法让它工作。
我有一个这样的Typescript源文件:
export namespace Init {
export function index() {
// do some things
}
}
export function blahblah() { console.log('blahblah') }
它位于同一文件夹src/ts/*.ts
中的其他一些来源旁边。我的webpack.config.js看起来像这样:
'use strict';
module.exports = {
context: __dirname,
output: {
filename: 'bundle.js',
library: 'bitthicket',
},
devtool: 'sourcemap',
resolve: {
extensions: [ '.ts', '.tsx', '.js' ]
},
module: {
rules: [
{ test: /\.tsx?$/, exclude: /node_modules/, loader: 'ts-loader' }
]
}
}
最后,我的gulpfile.js看起来像这样:
var gulp = require('gulp')
var gutil = require('gulp-util')
var plumber = require('gulp-plumber')
var watch = require('gulp-watch')
var sass = require('gulp-sass')
var ts = require('gulp-typescript')
var clean = require('gulp-clean')
var webpack = require('webpack')
var webpack_config = require('./webpack.config.js')
var webpack_stream = require('webpack-stream')
let _sass = () =>
gulp.src('src/css/**/*.scss')
.pipe(plumber())
.pipe(sass())
.pipe(gulp.dest('static/css'))
.on('end', () => gutil.log('_sass: done'))
let _webpack = () =>
gulp.src('src/ts/**/*.ts')
.pipe(plumber())
.pipe(webpack_stream(webpack_config, webpack))
.pipe(gulp.dest('static/js'))
.on('end', () => gutil.log('_webpack: done'))
gulp.task('build:sass', _sass)
gulp.task('clean:sass', () => gulp.src('static/css/**/*').pipe(clean()))
gulp.task('watch:sass', () => watch('src/css/**/*.scss', () => _sass()))
gulp.task('build:webpack', _webpack)
gulp.task('clean:ts', () => gulp.src('static/js/**/*').pipe(clean()))
gulp.task('watch:webpack', () => watch('src/ts/**/*.ts', () => _webpack()))
gulp.task('watch', ['watch:sass', 'watch:webpack'])
gulp.task('clean', ['clean:sass', 'clean:ts'])
gulp.task('build', ['build:sass', 'build:webpack'])
gulp.task('default', ['clean', 'build'])
在html文件中:
<script src="bundle.js" async></script>
<script>window.onload = function() { console.log(bitthicket); }</script>
正如我所理解的那样,正在发生的事情是webpack将源代码管理列表作为条目文件获取,就像它们被放置在命令行上一样webpack {src list} bundle.js
。但是我设置了library
输出选项,bitthicket
变量确实设置了,但它是一个空对象。 Init.index
发生了什么?
编辑:我将export关键字添加到Init
命名空间,以及一个普通函数init.ts
以查看会发生什么 - 但结果对象仍然没有这些功能。
以下是生成的webpack bootstrapper参数:
/***/ }),
/* 1 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
exports.__esModule = true;
var _ = __webpack_require__(2);
var Init;
(function (Init) {
function index() {
Nav.attachNavbarScrollWatcher();
document.addEventListener('scroll', function (event) {
var articles = document.querySelectorAll('.featured column.summary article');
var visibleArticle = _.find(articles, function (el) { return Util.isElementInViewport(el); });
console.log("{0} just became visible", visibleArticle);
});
}
Init.index = index;
})(Init = exports.Init || (exports.Init = {}));
function blahblah() {
console.log('blahblah');
}
exports.blahblah = blahblah;
/***/ }),
如您所见,此块中已分配exports.blahblah
和exports.Init.index
- 但我在浏览器中返回的对象如下所示:
答案 0 :(得分:1)
我的问题的真正答案是
我只是忽略了什么打字稿调用命名空间和模块之间的关系,以及webpack认为模块是什么之间的关系。
在完成此练习之后,我甚至不确定Typescript命名空间的重点是什么,除非您有一个使用tsc
和tsconfig.json
的多阶段构建过程创建多个已转换的bundle,稍后将由Webpack等其他加载器重新捆绑。
无论如何,要点:
Typescript&#34;名称空间&#34;对Webpack毫无意义(更具体地说,ts-loader
:见dow jones dot graph)。 Webpack无法遍历 namespace 依赖项,因此您最终会在bundle中使用未定义的符号,这意味着webpackBootstrap函数也不知道如何以正确的顺序加载内容。我的捆绑包中的入口点有点像这样:
/* 0 */
/***/ (function(module, exports, __webpack_require__) {
__webpack_require__(1); // <-- actual entry point, exports are lost
__webpack_require__(2);
exports = __webpack_require__(4); // <-- not entry point, nothing is exported here anyway
/***/ }),
...
Webpack(和ts-loader
)需要一种它能理解的模块形式,以便让引导程序正确加载内容。
我仍然在使用Typescript命名空间来构建结构,但是我export
使用import
来表示对其他Typescript模块的依赖:
import * as _ from 'lodash'
import * as Nav from './nav'
import * as Util from './util'
export namespace Init {
// ...
}
主要的是将依赖关系表达为es2015-style import
/ export
s。