我在Webpack上使用React + Typescript,我试图在实际需要时加载我的一些React组件。
问题是,当通过延迟加载请求块时,出现以下错误:
未捕获的错误:加载块1失败。 (错误:http://localhost:58988/1.chunk.js) 在HTMLScriptElement.onScriptComplete(bootstrap:114)
此块成功生成且没有任何错误,只是路径错误-http://localhost:58988/1.chunk.js
,它应该是http://localhost:58988/dist/1.chunk.js
我也尝试过使用最新的React.lazy
来延迟加载React组件,但是我遇到了同样的问题。那么,有没有办法告诉编译器如何解析这些文件路径?
以下是一些代码:
MyComponent.tsx
import * as React from "react";
import * as ES5Promise from "promise";
export class MyComponent extends React.Component<{}, {}> {
constructor(props) {
super(props);
}
private readonly onLoadModuleClickHandler = (): void => {
import("./Button").then((module) => {
console.log(module);
});
}
render() {
return (
<div>
<input type="button" value="Load another module" onClick={this.onLoadModuleClickHandler}/>
</div>
);
}
}
tsconfig.json
{
"compilerOptions": {
"moduleResolution": "node",
"noImplicitAny": false,
"noEmitOnError": true,
"module": "esnext",
"removeComments": false,
"sourceMap": false,
"target": "es5",
"jsx": "react",
"noEmit": true,
"importHelpers": true,
"lib": ["dom", "es5", "es2015.promise"]
},
"exclude": [
"node_modules",
"wwwroot"
]
}
webpack.config.js
module.exports = {
entry: {
"app": "./src/App.tsx"
},
output: {
path: path.resolve(__dirname, 'wwwroot/dist'),
filename: "[name].bundle.js",
chunkFilename: "[name].chunk.js"
},
module: {
rules: [
{
test: /\.(ts|tsx)?$/,
use: "awesome-typescript-loader",
exclude: /node_modules/
},
{
test: /\.(css|less)?$/,
use: [{
loader: "style-loader"
}, {
loader: "css-loader?modules&localIdentName=[local]--[hash:base64:5]"
}, {
loader: "less-loader"
}]
},
]
},
resolve: {
extensions: [".js", ".jsx", ".ts", ".tsx", ".css", ".less"]
}
};
答案 0 :(得分:7)
重新部署时,在重建应用捆绑包时,请确保不使用先前的块文件清理输出文件夹,因为已经加载了应用程序的用户将尝试获取不存在的先前的块文件。不再。
最好的方法是进行应用版本跟踪(使用AJAX并从数据库或动态配置文件中读取),并且当应用检测到更新版本时,向用户发送有关该版本的消息并询问他们重新加载页面。
答案 1 :(得分:4)
之所以会这样,是因为output.publicPath
默认为/
。
只需更新output.publicPath
使其指向您要的位置=> /dist/
。
答案 2 :(得分:1)
在我的例子中,window.addEventListener('error'...
没有触发,所以我重写了 console.error
方法如下:
const origin = console.error;
console.error = (error) => {
if (/Loading chunk [\d]+ failed/.test(error.message)) {
alert('A new version released. Need to relaod the page to apply changes.')
window.location.reload();
} else {
origin(error);
}
}
答案 3 :(得分:1)
将 output.publicPath
中的 webpack.config.js
的值设置为 /
将解决问题。
答案 4 :(得分:0)
我们不要对此过于关注。它只发生了5次。我相信有人excalidraw打开了一段时间,我们在此期间推送了一个新版本,当他们回来时,他们尝试加载一些惰性块,并且不再存在。
我们在Facebook上解决此问题的方法是,将以前的数据块在CDN上保留一周,如果捆绑包已使用了一周以上,则我们会强制为人们刷新该应用程序。这样,我们就不需要关心非常旧的版本。
以上回复来自vjeux。
我的计划是监听window.onerror中的错误,然后提示用户刷新浏览器。
window.addEventListener('error', e => {
// prompt user to confirm refresh
if (/Loading chunk [\d]+ failed/.test(e.message)) {
window.location.reload();
}
});