- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我正在尝试在 TypeScript 中创建一个框架并将其全部与 Webpack 捆绑在一起。
我遇到的问题是我不确定“入口点”应该是什么,当入口点设置为所有文件时,只有最后构建的文件会暴露给浏览器。
并且当设置单个入口点时,不会暴露任何依赖类(也就是只暴露入口点类)。
详细信息:
我的 TypeScript 框架比较大,目前有 140 多个模块,但完成后会增长到一千多个。
“bean”下的每个模块包含一个导出类和一些导入语句(从框架中的其他模块导入的类)
我的文件夹结构目前包括:
+---src
| +---API
| +---bean
| | +---base
| | | \---impl
| | +---categoryscheme
| | | \---impl
| | +---codelist
| | | \---impl
| | +---conceptscheme
| | | \---impl
| | +---constraint
| | | \---impl
| | +---datastructure
| | | \---impl
| | +---hierarchicalcodelist
| | | \---impl
| | +---metadatastructure
| | | \---impl
| | +---organisation
| | | \---Impl
| | +---reference
| | \---structuremap
| | \---impl
| +---enums
| +---typings
| \---util
其中每个 impl 包含一个导出的类,父文件夹包含接口(interface)。
我的第一个问题是这个框架不是一个应用程序,也不是一个单一的文件库,它是为人们设计的,可以做这样的事情:
var f = new CodeListBeanImpl();
或他们选择的任何类(class)。
无需赘述,这些文件的原因是存在定义的结构层次结构。
例如,文件夹 codelist/impl 中的类“CodelistBeanImpl”具有以下层次结构: see image
每个文件分布在许多不同的位置在核心文件夹中。
因此,如果没有明确的框架“入口点”,我无法让 webpack 将所有模块简单地捆绑到一个文件中,并使其可供浏览器调用。
这是我的 webpack 配置:
const CircularDependencyPlugin = require('circular-dependency-plugin');
const path = require("path");
const glob = require("glob");
let list = glob.sync("./src/**/*.ts");
module.exports = {
entry: list,
devtool: 'source-eval-map',
module: {
rules: [
{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: [
/node_modules/
]
}
]
},
mode: "development",
resolve: {
extensions: [ '.tsx', '.ts', '.js' ],
modules: ["./node_modules", "./src"]
},
plugins: [
new CircularDependencyPlugin({
failOnError: true,
cwd: process.cwd(),
}),
],
output: {
path: path.join(__dirname, "dist"),
filename: "bundle.js",
libraryTarget: "window",
library: "IMJS",
}
};
现在,如您所见,我希望打包所有模块,所以我的入口点是每个文件,以确保打包所有模块和类。
这是 webpack 的输出:
[./src/API/IM.ts] 2.74 KiB {main} [built]
[./src/bean/base/impl/AnnotableBeanImpl.ts] 5.93 KiB {main} [built]
[./src/bean/base/impl/AnnotationBeanImpl.ts] 5.5 KiB {main} [built]
[./src/bean/base/impl/BeanImpl.ts] 3.52 KiB {main} [built]
[./src/bean/base/impl/ComponentBeanImpl.ts] 5.44 KiB {main} [built]
[./src/bean/base/impl/DataMetricsBeanImpl.ts] 3.22 KiB {main} [built]
[./src/bean/base/impl/IdentifiableBeanImpl.ts] 6.67 KiB {main} [built]
[./src/bean/base/impl/ItemBeanImpl.ts] 1.15 KiB {main} [built]
[./src/bean/base/impl/ItemSchemeBeanImpl.ts] 6.36 KiB {main} [built]
[./src/bean/base/impl/JsonBeanImpl.ts] 6.34 KiB {main} [built]
[./src/bean/base/impl/MaintainableBeanImpl.ts] 9.27 KiB {main} [built]
[./src/bean/base/impl/MetricsBeanImpl.ts] 2.03 KiB {main} [built]
[./src/bean/base/impl/NameableBeanImpl.ts] 6.97 KiB {main} [built]
[./src/bean/base/impl/PseudoHierarchyItemImpl.ts] 2.53 KiB {main} [built]
+ 181 hidden modules
到目前为止看起来不错......
但是,当我这样做的时候。并在浏览器中运行“bundle.js”文件,唯一的 IMJS(我决定使用的库名称)是最后构建的文件: image of chrome console
所以我尝试做一个单一的“入口点”作为测试,看看我是否能得到除一个文件以外的任何东西。
我将 entry: list,
更改为 entry: "./src/bean/codelist/impl/CodelistBeanImpl.ts",
然后再次构建它,这次只构建了一小部分文件: Webpack output of single entry point
但是,当我转到 Chrome 控制台时,我唯一可用的类是“CodelistBeanImpl”,它都不是父类(super class),所以我可以这样做:
var f = new IMJS.CodelistBeanImpl();
但是如果我想,比如说,对“PseudoHierarchyItemSchemeImpl”进行 instanceof 检查它会声明“PseudoHierarchyItemSchemeImpl”未定义,事实上,除了代码列表 bean 之外没有任何其他定义。
这甚至可以用 webpack 实现吗?还是我需要使用不同的打包机?
仅供引用,这是我的 tsconfig.json:
{
"compilerOptions": {
"outDir": "./lib/",
"noImplicitAny": true,
"moduleResolution": "node",
"baseUrl": "./src",
"module": "amd",
"target": "es5",
"allowJs": true,
"sourceMap": true,
"strict": true,
"noEmit": false,
"checkJs": false,
"strictNullChecks": false,
"strictFunctionTypes": true,
"downlevelIteration": true,
"lib":[
"es2015",
"dom"
]
},
"compileOnSave": true,
"include": ["./src/**/*.ts"]
}
最佳答案
我设法实现了我想要在 src 文件夹之外创建一个名为“main.ts”的文件,并以编程方式为每个类创建导出。
这不是最好的解决方案,所以如果有人有更好的主意,请保持开放:
webpack.config.js:
function createEntryPoint(){
console.log("creating entry point...");
const glob = require("glob");
let typeScriptConfigFile = require("./tsconfig");
let baseUrl = typeScriptConfigFile.compilerOptions.baseUrl;
if(!baseUrl){
throw new Error("Unable to find baseUrl in tsconfig");
}
let list = glob.sync(baseUrl+"/**/*.ts");
const fs = require('fs');
let num = 0;
fs.writeFileSync('./main.ts', (function () {
let strToReturn = "";
for (let file of list) {
num++;
let fromBaseUrl = file.replace(baseUrl+"/", "");
fromBaseUrl = fromBaseUrl.replace(".ts", "");
strToReturn += "export * from '" + fromBaseUrl + "'; \n";
}
return strToReturn;
}()));
console.log("Entry point created: " +num + " modules exported");
}
createEntryPoint();
入口点是:
entry: "./main.ts",
关于typescript - 如何用Webpack在Typescript中打包大型框架,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53636463/
我是一名优秀的程序员,十分优秀!