我正在尝试将Web应用程序模块化,以下是一些要点:
所以我的问题是如何使用webpack做到这一点?我知道动态的import()
功能,但是它需要一个我没有的模块路径,因为以后应该定义它,并且每个路由都应该有所不同。我正在考虑编写一个插件来覆盖webpack本身提供的块获取内部信息,但是也许有更好的方法吗?
答案 0 :(得分:0)
我本人实际上已经经历过这种痛苦。 Webpack和Browserify 可以做到这一点,但我并不十分喜欢它的实现方式。您确实是正确的-您需要事先知道可以/需要加载什么。
我在当前设置中使用Go和GopherJS,但我上一个使用了NodeJS,SystemJS和RollupJS,但直到今天我仍在使用SystemJS和RollupJS组件。
对于捆绑,您需要提前考虑,我个人捆绑了主要组件,通常将其称为core.bundle.js。在我的项目中,我将所有客户端内容放入其自己的jslib文件夹中:
我使用TypeScript,所以在./src/index.ts中,我引用了我的主库..:
//@ts-ignore
import * as jquery from "jquery";
import * as popper from "popper.js"
import * as bootstrap from "../vendor/bootstrap/index.js"
import * as backbone from "backbone"
import * as lodash from "lodash"
//@ts-ignore
window.jquery = window.jQuery = window.$ = jquery;
//@ts-ignore
window.popper = popper;
//@ts-ignore
window.bootstrap = bootstrap;
//@ts-ignore
window.Backbone = backbone;
//@ts-ignore
window._ = window.lodash = lodash;
道歉,但GopherJS对于在某些地方需要某些东西可能会很有趣-但至少所有内容都是在需要放置在该窗口对象上的。
然后在同一文件中有动态加载器:
import * as SystemJS from 'systemjs';
import * as Promise from "bluebird";
export class DynamicModuleManager {
constructor() {
//load up the main package and initialise SystemJS for use
SystemJS.config({
baseURL: '/_pkg', //your dynamic requires will use this folder for the root
meta: { '*': { scriptLoad: true } }
});
}
public init() {
//Register the modules you have already loaded!
//@ts-ignore
SystemJS.set('lodash', SystemJS.newModule({
//@ts-ignore
"default": window.lodash
}));
//@ts-ignore
SystemJS.set('jquery', SystemJS.newModule({
//@ts-ignore
"default": window.$
}));
//Optionally add some shim/fake modules to allow NodeJS stuff to be used if needed
//@ts-ignore
SystemJS.set('child_process', SystemJS.newModule({
ChildProcess: {}
}));
}
public import(moduleId:string) {
return SystemJS.import(moduleId).then((m) => {
console.log(`Loading Module: ${moduleId}`);
//m is the module object just like you had "required" it
return m
});
}
}
如果您使用打字稿,那么我的tsconfig对于核心捆绑包是这样的:
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"lib": ["es2015", "dom"],
"baseUrl": "./src/",
"outDir": "./build/",
"inlineSourceMap": true,
"paths": {
"*": [
"./node_modules/*"
]
}
},
"exclude": [
"node_modules"
],
"include": [
"src/**/*"
]
}
然后汇总配置如下:
// rollup.config.js
import builtins from 'rollup-plugin-node-builtins';
import nodeResolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
import json from 'rollup-plugin-json';
export default {
input: './build/index.js',
output: {
file: '../assets/js/core.bundle.js',
format: 'cjs'
},
name: 'core_bundle',
plugins: [
json(),
builtins(),
nodeResolve(),
commonjs(),
]
}
我不使用rollup-typescript插件,因为它导致了我的问题,所以它分三个阶段进行构建:
$ cd ~/your_web_project/jslib
$ npm init && npm install --save jquery... [OTHER DEPS]
## When you clone just make sure to do npm install
$ tsc -p tsconfig.json
## if you are running typescript remember to install globally
$ rollup -c
## again install globally
现在您将拥有〜/ your_web_project / assets / js / core.bundle.js
因此,现在您可以构建其他模块/块。对于上述配置,您需要将它们放在您喜欢的服务器提供的目录中,或者从节点内的路由中获取,例如:GET / _pkg /:module_name->〜/ your_web_project / resources / _pkg /:module_name.js < / p>
在您的模块上,您需要做的就是设置另一个jslib文件夹,大致相同,但是这次向rollupjs介绍您的外部软件包...
Dynamically Loadable VSCode/Monaco Environment for Golang Folder Structure
// rollup.config.js
import nodeResolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
import postcss from 'rollup-plugin-postcss';
import json from 'rollup-plugin-json';
import alias from 'rollup-plugin-alias';
import babel from 'rollup-plugin-babel';
import * as filepath from "path"
//export an array of webpack configs for multiple modules..
export default [
{
input: './build/index.js',
external : ["lodash", "jquery"], //make sure to make the module aware of anything external otherwise it will get bundled!
output: {
file: '../resources/devide.go.js',
format: 'cjs',
},
plugins: [
nodeResolve({
module: true,
jsnext: true,
extensions: [ '.js', '.json' ]
}),
commonjs(),
alias({
'golangcli': filepath.resolve(__dirname, 'build/golangcli/client'),
'vscode': require.resolve('monaco-languageclient/lib/vscode-compatibility')
}),
json(),
postcss({
plugins: [] //you can even embed CSS in your sources and have it load here...
}),
babel({
"presets": ["@babel/preset-env"],
"plugins": ["@babel/plugin-syntax-dynamic-import"]
})
]
}
];
上面的示例有点极端,因为在与Rollup捆绑在一起之前我使用Typescript和Babel。
tsconfig也需要进行一些细微更改:
{
"compilerOptions": {
"noImplicitAny": false,
"module": "es2015",
"target": "es2015",
"lib": ["es2015", "dom"],
"baseUrl": "./src/",
"outDir": "./build/",
"inlineSourceMap": false,
"moduleResolution": "node",
"skipLibCheck": true,
"paths": {
"*": [
"./node_modules/*"
]
}
},
"include": [
"src/**/*"
]
}
这将在源开始汇总时强制进行适当的树抖动,并确保仅导入实际需要的内容。当Monaco有效负载超过10MB时,这一点很重要!
Rollup是一个很好的工具包,我什至可以使用它来汇总整个服务器端代码库,以便可以复制它们并运行依赖项,并且所有这些都没有问题(只要您拥有节点二进制文件),并且效果很好使用Golang,Buffalo和GopherJS设置。
以上问题是我长期努力解决的问题,我认为这是我有史以来的第一个答案。毫无疑问,上述解决方案中存在漏洞,但希望它能激发人们的灵感!