- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我对 Webpack 很陌生,如果这是一个愚蠢的问题,请耐心等待。
我的目标是将旧的基于 AMD 的代码库转换为基于 ES6 模块的解决方案。我正在努力处理动态import()
s。所以我的应用程序路由器基于模块工作,即每个路由都映射到模块路径,然后 require
d。自从我了解将包含哪些模块,我只是将这些动态导入的模块添加到我的 r.js 配置中,并且能够在单个文件中构建所有内容,所有 require 调用仍然有效。
现在,我正在尝试对 ES6 模块和 Webpack 做同样的事情。使用我的 devmode 这没问题,因为我可以替换 require()
与 import()
.但是我不能让它与捆绑一起工作。 Webpack 会拆分我的代码(无论如何仍然无法加载动态模块),或者 - 如果我对 entry
使用数组格式config,动态模块是 包含在捆绑包中,但加载仍然失败:Error: Cannot find module '/src/app/DynClass.js'
这就是我的 Webpack 配置的样子:
const webpack = require('webpack');
const path = require('path');
module.exports = {
mode: "development",
entry: ['./main.js', './app/DynClass.js'],
output: {
filename: 'main.js',
path: path.resolve(__dirname, "../client/")
},
resolve: {
alias: {
"/src": path.resolve(__dirname, '')
}
},
module: {
rules: [
{
test: /\.tpl$/i,
use: 'raw-loader',
},
]
}
};
最佳答案
所以,是的,经过多次摆弄,隧道尽头似乎有一盏灯。尽管如此,这不是一个 100% 的解决方案,而且它肯定不适合胆小的人,因为它非常丑陋和脆弱。但我仍然想与您分享我的方法:
1)手动解析我的路线配置
我的路由器使用如下配置文件:
import StaticClass from "/src/app/StaticClass.js";
export default {
StaticClass: {
match: /^\//,
module: StaticClass
},
DynClass: {
match: /^\//,
module: "/src/app/DynClass.js"
}
};
如您所见,导出是一个对象,其键充当路由 id,一个对象包含匹配项(基于正则表达式)和路由匹配时应由路由器执行的模块。我可以为我的路由器提供一个构造函数(或一个对象),用于立即可用的模块(即包含在主 block 中),或者如果模块值是一个字符串,这意味着路由器必须通过动态加载这个模块使用字符串中指定的路径。
const path = require("path");
const fs = require("fs");
let routesSource = fs.readFileSync(path.resolve(__dirname, "app/routes.js"), "utf8");
routesSource = routesSource.substr(routesSource.indexOf("export default"));
routesSource = routesSource.replace(/module:\s*((?!".*").)*$/gm, "module: undefined,");
routesSource = routesSource.replace(/\r?\n|\r/g, "").replace("export default", "var routes = ");
eval(routesSource);
let dummySource = Object.entries(routes).reduce((acc, [routeName, routeConfig]) => {
if (typeof routeConfig.module === "string") {
return acc + `import(/* webpackChunkName: "${routeName}" */"${routeConfig.module}");`;
}
return acc;
}, "") + "export default ''";
(是的,我知道这很丑,也有点脆,所以这肯定可以做得更好)
DynClass: {
match: /^\//,
module: "/src/app/DynClass.js"
}
变成:
import(/* webpackChunkName: "DynClass" */"/src/app/DynClass.js");
所以路由 id 就变成了 block 的名称!
virtual-module-webpack-plugin
:
plugins: [
new VirtualModulePlugin({
moduleName: "./app/dummy.js",
contents: dummySource
})
],
在哪里
dummySource
只是一个字符串,其中包含我刚刚生成的虚拟模块的源代码。现在,这个模块被拉进来,“虚拟导入”可以被 webpack 处理。但是等等,我仍然需要导入虚拟模块,但是在我的开发模式下我没有任何模块(我在本地使用所有东西,所以没有加载器)。
let isDev = false;
/** @remove */
isDev = true;
/** @endremove */
if (isDev) { import('./app/dummy.js'); }
当我处于开发模式时,“dummy.js”只是一个空的 stub 模块。在构建时(使用
webpack-loader-clean-pragma
加载器)删除了特殊注释之间的部分,因此当 webpack “看到”
dummy.js
的导入时,从那时起,此代码将不会在构建本身中执行
isDev
计算结果为
false
.而且由于我们已经定义了具有相同路径的虚拟模块,因此在构建时就像我想要的那样包含了虚拟模块,当然所有的依赖关系也都得到了解决。
import routes from './app/routes.js';
Object.entries(routes).forEach(async ([routeId, route]) => {
if (typeof route.module === "function") {
new route.module;
} else {
const result = await import(route.module);
new result.default;
}
});
(请注意,这不是实际的路由器代码,足以帮助我完成我的 PoC)
/** @remove */
const result = await import(route.module);
new result.default;
/** @endremove */
if (!isDev) {
if (typeof route.module === "string") { await __webpack_require__.e(routeId); }
const result = __webpack_require__(route.module.replace("/src", "."));
new result.default;
}
现在,开发环境的加载代码刚刚被剥离出来,还有另一个内部使用 webpack 的加载代码。我还检查模块值是函数还是字符串,如果是后者,我调用内部
require.ensure
加载正确 block 的函数:
await __webpack_require__.e(routeId);
.还记得我在生成虚拟模块时命名了我的 block 吗?这就是为什么我现在仍然可以找到它们的原因!
module1~module2.bundle.js
的 block 。 ,打破我的构建。为了解决这个问题,我需要确保所有这些共享模块都进入我称为“共享”的特定命名包中:
optimization: {
splitChunks: {
chunks: "all",
name: "shared"
}
}
在生产模式下,我只需在请求任何依赖于它的动态模块之前手动加载这个 block :
if (!isDev) {
await __webpack_require__.e("shared");
}
同样,此代码仅在生产模式下运行!
optimization: {
namedChunks: true,
namedModules: true
}
是的,你有它!正如我所说,这并不漂亮,但似乎可以工作,至少在我简化的测试设置中是这样。我真的希望当我做所有其他事情(如 ESLint、SCSS 等)时,没有任何障碍在我面前!
关于javascript - 如何在 Webpack Bundle 中包含手动 import(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55052636/
我有一个类似于以下的结构。 class A { string title; List bItem; } class B { int pric
本地流 和 远程流 两者都是“媒体流列表 ”。 本地流 包含“本地媒体流 ” 对象 但是,远程流 包含“媒体流 ” 对象 为什么差别这么大? 当我使用“本地流 “- 这个对我有用: localVide
我正在尝试将 8 列虚拟变量转换为 8 级排名的一列。 我试图用这个公式来做到这一点: =IF(OR(A1="1");"1";IF(OR(B1="1");"2";IF(OR(C1="1");"3";I
我正在使用面向对象编程在 Python 中创建一个有点复杂的棋盘游戏的实现。 我的问题是,许多这些对象应该能够与其他对象交互,即使它们不包含在其中。 例如Game是一个对象,其中包含PointTrac
有没有办法获取与 contains 语句匹配的最深元素? 基本上,如果我有嵌套的 div,我想要最后一个元素而不是父元素: Needle $("div:contains('Needle')")
出于某种原因,我无法在 Google 上找到答案!但是使用 SQL contains 函数我怎么能告诉它从字符串的开头开始,即我正在寻找等同于的全文 喜欢 'some_term%'。 我知道我可以使用
我正在尝试创建一个正则表达式来匹配具有 3 个或更多元音的字符串。 我试过这个: [aeiou]{3,} 但它仅在元音按顺序排列时才有效。有什么建议吗? 例如: 塞缪尔 -> 有效 琼 -> 无效 S
嘿所以我遇到了这样的情况,我从数据库中拉回一个客户,并通过包含的方式包含所有案例研究 return (from c in db.Clients.Include("CaseStudies")
如果关键字是子字符串,我无法弄清楚为什么这个函数不返回结果。 const string = 'cake'; const substring = 'cak'; console.log(string.in
我正在尝试将包含特定文本字符串的任何元素更改为红色。在我的示例中,我可以将子元素变为蓝色,但是我编写“替换我”行的方式有些不正确;红色不会发生变化。我注意到“contains”方法通常写为 :cont
我想问一下我是否可以要求/包含一个语法错误的文件,如果不能,则require/include返回一个值,这样我就知道所需/包含的文件存在语法错误并且不能被要求/包含? file.php语法错误 inc
我想为所有包含youtube链接的链接添加一个rel。 这就是我正在使用的东西-但它没有用。有任何想法吗? $('a [href:contains(“youtube.com”)]')。attr('re
我正在尝试在 Elasticsearch 中查询。除搜索中出现“/”外,此功能均正常运行。查询如下所示 GET styling_rules/product_line_filters/_search {
我正在开发名为eBookRepository的ASP.NET MVC应用程序,其中包含在线图书。 电子书具有自己的标题,作者等。因此,现在我正在尝试实现搜索机制。我必须使用Elasticsearch作
我已阅读Firebase Documentation并且不明白什么是 .contains()。 以下是文档中 Firebase 数据库的示例规则: { "rules": { "rooms"
我的问题是我可以给出条件[ 'BookTitleMaster.id' => $xtitid, ] 如下所示 $bbookinfs = $this->BookStockin->BookIssue->fi
我需要能够使用 | 检查模式在他们中。例如,对于像“dtest|test”这样的字符串,像 d*|*t 这样的表达式应该返回 true。 我不是正则表达式英雄,所以我只是尝试了一些事情,例如: Reg
我想创建一个正则表达式来不匹配某些单词... 我的字符:var test = "é123rr;and;ià456;or;456543" 我的正则表达式:test.match(\((?!and)(?!o
我在 XSLT 中有一个名为 variable_name 的变量,如果相关产品具有名称为 A 或 B 或两者均为 A & 的属性,我将尝试将其设置为 1 B.
您好,我想让接待员和经理能够查看工作类型和费率并随后进行更新。但是技术人员只能查看不能更新。该图是否有效? 我读到扩展用例是由发起基本用例的参与者发起的。我应该如何区分技术人员只能启动基本案例而不能启
我是一名优秀的程序员,十分优秀!