Я пытаюсь создать фреймворк на 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 содержит экспортированный класс, а родительские папки содержат интерфейсы.
Моя первая проблема заключается в том, что этот фреймворк не является приложением или однофайловой библиотекой, он предназначен для людей, которые могут делать такие вещи, как:
var f = new CodeListBeanImpl();
или какой бы класс они ни выбрали.
Не вдаваясь в подробности, причина этих файлов в том, что существует определенная Иерархия структур.
Например, класс CodelistBeanImpl в папке codelist / impl имеет следующую иерархию: см изображение
Каждый файл разбросан по разным адресам. в основной папке.
Итак, без четкой «точки входа» в структуру я не могу заставить 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 (имя библиотеки, которое я решил использовать) - это ПОСЛЕДНИЙ созданный файл: образ хромированной консоли
Поэтому я пытаюсь сделать единственную «точку входа» в качестве теста, чтобы увидеть, могу ли я получить что-нибудь, кроме одного файла.
Меняю entry: list, на entry: "./src/bean/codelist/impl/CodelistBeanImpl.ts",
и построим его снова, на этот раз будет собран только небольшой набор файлов: Вывод Webpack для единой точки входа
Однако, когда я перехожу к консоли Chrome, единственный доступный мне класс - это CodelistBeanImpl, ни один из его суперклассов, поэтому я могу:
var f = new IMJS.CodelistBeanImpl();
но если я хочу, скажем, выполнить проверку instanceof для 'PseudoHierarchyItemSchemeImpl' он бы заявил, что «PseudoHierarchyItemSchemeImpl» не определен, фактически, не определено ничего, кроме bean-компонента списка кодов.
Возможно ли это даже с веб-пакетом? или мне нужно использовать другой упаковщик?
просто для справки, вот мой 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.info("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.info("Entry point created: " +num + " modules exported");
}
createEntryPoint();
и точка входа:
entry: "./main.ts",