Webpack 分块。没有内容出现 - 块未加载
Webpack chunking. No content appearing - chunks not loaded
我花了一天的时间来解决这个烦人但我敢肯定的简单问题。
我正在尝试将我的 bundle.js 分成块以优化网站加载时间。
这是我的 webpack.config 文件:
module.exports = {
devServer: {
historyApiFallback: true
},
entry: {
index: ["./src/index.js"],
vendor: [
"react",
"react-dom",
"react-redux",
"react-router",
"react-router-dom",
"redux"
]
},
output: {
path: __dirname + '/public/views',
filename: "[name].js",
publicPath: "/views/"
},
module: {
loaders: [
{
test: /\.js$/,
loader: "babel-loader",
exclude: [/node_modules/, /pdfmake.js$/]
},
{
test: /\.json$/,
loader: "json-loader"
}
]
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: "vendor",
filename: "vendor.js",
minChunks: Infinity
}),
new webpack.optimize.CommonsChunkPlugin({
name: "meta",
chunks: ["vendor"],
filename: "meta.js"
}),
new webpack.NamedModulesPlugin(),
new HtmlWebpackPlugin({
title: "Deals",
filename: __dirname + "/views/index.ejs",
template: __dirname + "/views/template.ejs",
inject: false
}),
new PreloadWebpackPlugin({
rel: "preload",
as: "script",
include: "all"
}),
new webpack.optimize.OccurrenceOrderPlugin(),
]
};
这是我的简化 index.ejs,由 运行 webpack 代码创建的文件,结果来自 template.ejs :
<!DOCTYPE html>
<html lang="en">
<head>
<link href="/pace.css" rel="stylesheet" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=yes">
<meta charset="utf-8">
<link rel="stylesheet" href="/style.css">
<link rel="canonical" href="http://verygoodprof.fr/" />
<link rel="preload" as="script" href="/views/index.js">
<link rel="preload" as="script" href="/views/vendor.js">
<link rel="preload" as="script" href="/views/meta.js">
</head>
<body>
<noscript>
<a href="http://enable-javascript.com/">Javascript must me enabled to use this site.</a>
</noscript>
<div class="text-center root" id="root">
</div>
</body>
</html>
在这里,我看到我有预加载的块,根据需要动态编写,并且这些块位于正确的文件夹中,是在 运行 webpack 代码之后创建的。
这是我的 index.js 文件(React),据称是 webpack.config 文件
中的索引条目
ReactDOM.render(
<Provider store={createStoreWithMiddleware(reducers)}>
<AppInit>
<BrowserRouter>
<div style={{ height: "100%" }}>
<ProfRegisteringModal />
<Switch>
{/* <Route path="/inscription/:user" component={Registering} />
<Route path="/inscription" component={Registering} />
<Route path="/connexion" component={SigningIn} />
<Route path="/equipe" component={TeamPres} />
<Route path="/" component={AppContainer} /> */}
<Route
path="/inscription/:user"
getComponent={(location, callback) => {
require.ensure(
[],
function(require) {
callback(
null,
require("./components/registering/registering_landing_page.js")
);
},
"registerChunk"
);
}}
/>
<Route
path="/inscription"
getComponent={(location, callback) => {
require.ensure(
[],
function(require) {
callback(
null,
require("./components/registering/registering_landing_page.js")
);
},
"registerChunk"
);
}}
/>
<Route
path="/connexion"
getComponent={(location, callback) => {
require.ensure(
[],
function(require) {
callback(
null,
require("./containers/registering/signing_in.js")
);
},
"signinChunk"
);
}}
/>
<Route
path="/equipe"
getComponent={(location, callback) => {
require.ensure(
[],
function(require) {
callback(null, require("./components/team_pres.js"));
},
"teampresChunk"
);
}}
/>
<Route
path="/"
getComponent={(location, callback) => {
require.ensure(
[],
function(require) {
callback(null, require("./containers/app_container.js"));
},
"appContainerChunk"
);
}}
/>
</Switch>
</div>
</BrowserRouter>
</AppInit>
</Provider>,
document.querySelector(".root")
);
我注意到的第一件事是应该构建的块是为 vendor 和 meta 正确构建的,但不是我的内部反应组件。但这不是主要问题,事实是,当 运行 本地服务器时,我根本看不到我的 React 应用程序。 index.ejs 文件在我检查控制台时已正确加载。
使用包含所有内容(无块)的简单 bundle.js 文件时一切正常。用 index.ejs 指向它作为
<script src="/views/bundle.js"></script>
非常感谢您的帮助!
编辑
这个 webpack.config 文件使它工作(感谢@margaretkru):
module.exports = {
devServer: {
historyApiFallback: true
},
entry: {
app:"./src/index.js",
vendor: [
"axios",
"jquery",
"react",
"react-dom",
"react-redux",
"react-router",
"react-router-dom",
"redux"
]
},
output: {
path: __dirname + '/public/views',
filename: "[name].js",
publicPath: "/views/"
},
module: {
loaders: [
{
test: /\.js$/,
loader: "babel-loader",
exclude: [/node_modules/, /pdfmake.js$/]
},
{
test: /\.json$/,
loader: "json-loader"
}
]
},
plugins: [
new webpack.NamedModulesPlugin(),
new HtmlWebpackPlugin({
filename: __dirname + "/views/index.ejs",
template: __dirname + "/views/template.ejs",
inject: 'body',
chunks: ['vendor', 'app'],
chunksSortMode: 'manual'
}),
new PreloadWebpackPlugin({
rel: "preload",
include: ["vendor", "app"]
}),
new webpack.optimize.OccurrenceOrderPlugin(),
]
};new webpack.optimize.CommonsChunkPlugin({
name: "vendor",
minChunks: Infinity
}),
new webpack.NamedModulesPlugin(),
new HtmlWebpackPlugin({
filename: __dirname + "/views/index.ejs",
template: __dirname + "/views/template.ejs",
inject: 'body',
chunks: ['vendor', 'app'],
chunksSortMode: 'manual'
}),
new PreloadWebpackPlugin({
rel: "preload",
include: ["vendor", "app"]
}),
new webpack.optimize.OccurrenceOrderPlugin(),
]
};
真正的问题不是加载脚本的顺序,而是我实际上并没有在 "pre-loading" 它们之后加载脚本:HTMLWebpackPlugin 的 "inject" 行帮助了它,因为它注入了这两行:
<script src="/views/vendor.js"/>
<script src="/views/app.js"/>
在我的index.ejs体内
index.ejs 中加载的脚本顺序不正确。现在是:
<link rel="preload" as="script" href="/views/index.js">
<link rel="preload" as="script" href="/views/vendor.js">
这意味着您的 index.js
将在 vendor.js
之前加载,导致您的应用根本不会出现。首先应加载应用程序的所有依赖项 (vendor.js
),然后才加载 index.js
,因为您需要在执行自定义代码时存在依赖项。所以应该是:
<link rel="preload" as="script" href="/views/vendor.js">
<link rel="preload" as="script" href="/views/index.js">
编辑:
正如我们最终发现的那样,问题不在于脚本的顺序,而是由于脚本实际上并未在 html
中加载。为此,它们需要作为块添加到 HtmlWebpackPlugin
中并注入到 index.html
:
new HtmlWebpackPlugin({
title: "Deals",
filename: __dirname + "/views/index.ejs",
template: __dirname + "/views/template.ejs",
inject: 'body',
chunks: ['vendor', 'index']
})
此外,块 meta
的配置已完全删除。所有其余配置(包括 PreloadWebpackPlugin
)都很好。
我花了一天的时间来解决这个烦人但我敢肯定的简单问题。 我正在尝试将我的 bundle.js 分成块以优化网站加载时间。
这是我的 webpack.config 文件:
module.exports = {
devServer: {
historyApiFallback: true
},
entry: {
index: ["./src/index.js"],
vendor: [
"react",
"react-dom",
"react-redux",
"react-router",
"react-router-dom",
"redux"
]
},
output: {
path: __dirname + '/public/views',
filename: "[name].js",
publicPath: "/views/"
},
module: {
loaders: [
{
test: /\.js$/,
loader: "babel-loader",
exclude: [/node_modules/, /pdfmake.js$/]
},
{
test: /\.json$/,
loader: "json-loader"
}
]
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: "vendor",
filename: "vendor.js",
minChunks: Infinity
}),
new webpack.optimize.CommonsChunkPlugin({
name: "meta",
chunks: ["vendor"],
filename: "meta.js"
}),
new webpack.NamedModulesPlugin(),
new HtmlWebpackPlugin({
title: "Deals",
filename: __dirname + "/views/index.ejs",
template: __dirname + "/views/template.ejs",
inject: false
}),
new PreloadWebpackPlugin({
rel: "preload",
as: "script",
include: "all"
}),
new webpack.optimize.OccurrenceOrderPlugin(),
]
};
这是我的简化 index.ejs,由 运行 webpack 代码创建的文件,结果来自 template.ejs :
<!DOCTYPE html>
<html lang="en">
<head>
<link href="/pace.css" rel="stylesheet" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=yes">
<meta charset="utf-8">
<link rel="stylesheet" href="/style.css">
<link rel="canonical" href="http://verygoodprof.fr/" />
<link rel="preload" as="script" href="/views/index.js">
<link rel="preload" as="script" href="/views/vendor.js">
<link rel="preload" as="script" href="/views/meta.js">
</head>
<body>
<noscript>
<a href="http://enable-javascript.com/">Javascript must me enabled to use this site.</a>
</noscript>
<div class="text-center root" id="root">
</div>
</body>
</html>
在这里,我看到我有预加载的块,根据需要动态编写,并且这些块位于正确的文件夹中,是在 运行 webpack 代码之后创建的。
这是我的 index.js 文件(React),据称是 webpack.config 文件
中的索引条目ReactDOM.render(
<Provider store={createStoreWithMiddleware(reducers)}>
<AppInit>
<BrowserRouter>
<div style={{ height: "100%" }}>
<ProfRegisteringModal />
<Switch>
{/* <Route path="/inscription/:user" component={Registering} />
<Route path="/inscription" component={Registering} />
<Route path="/connexion" component={SigningIn} />
<Route path="/equipe" component={TeamPres} />
<Route path="/" component={AppContainer} /> */}
<Route
path="/inscription/:user"
getComponent={(location, callback) => {
require.ensure(
[],
function(require) {
callback(
null,
require("./components/registering/registering_landing_page.js")
);
},
"registerChunk"
);
}}
/>
<Route
path="/inscription"
getComponent={(location, callback) => {
require.ensure(
[],
function(require) {
callback(
null,
require("./components/registering/registering_landing_page.js")
);
},
"registerChunk"
);
}}
/>
<Route
path="/connexion"
getComponent={(location, callback) => {
require.ensure(
[],
function(require) {
callback(
null,
require("./containers/registering/signing_in.js")
);
},
"signinChunk"
);
}}
/>
<Route
path="/equipe"
getComponent={(location, callback) => {
require.ensure(
[],
function(require) {
callback(null, require("./components/team_pres.js"));
},
"teampresChunk"
);
}}
/>
<Route
path="/"
getComponent={(location, callback) => {
require.ensure(
[],
function(require) {
callback(null, require("./containers/app_container.js"));
},
"appContainerChunk"
);
}}
/>
</Switch>
</div>
</BrowserRouter>
</AppInit>
</Provider>,
document.querySelector(".root")
);
我注意到的第一件事是应该构建的块是为 vendor 和 meta 正确构建的,但不是我的内部反应组件。但这不是主要问题,事实是,当 运行 本地服务器时,我根本看不到我的 React 应用程序。 index.ejs 文件在我检查控制台时已正确加载。
使用包含所有内容(无块)的简单 bundle.js 文件时一切正常。用 index.ejs 指向它作为
<script src="/views/bundle.js"></script>
非常感谢您的帮助!
编辑
这个 webpack.config 文件使它工作(感谢@margaretkru):
module.exports = {
devServer: {
historyApiFallback: true
},
entry: {
app:"./src/index.js",
vendor: [
"axios",
"jquery",
"react",
"react-dom",
"react-redux",
"react-router",
"react-router-dom",
"redux"
]
},
output: {
path: __dirname + '/public/views',
filename: "[name].js",
publicPath: "/views/"
},
module: {
loaders: [
{
test: /\.js$/,
loader: "babel-loader",
exclude: [/node_modules/, /pdfmake.js$/]
},
{
test: /\.json$/,
loader: "json-loader"
}
]
},
plugins: [
new webpack.NamedModulesPlugin(),
new HtmlWebpackPlugin({
filename: __dirname + "/views/index.ejs",
template: __dirname + "/views/template.ejs",
inject: 'body',
chunks: ['vendor', 'app'],
chunksSortMode: 'manual'
}),
new PreloadWebpackPlugin({
rel: "preload",
include: ["vendor", "app"]
}),
new webpack.optimize.OccurrenceOrderPlugin(),
]
};new webpack.optimize.CommonsChunkPlugin({
name: "vendor",
minChunks: Infinity
}),
new webpack.NamedModulesPlugin(),
new HtmlWebpackPlugin({
filename: __dirname + "/views/index.ejs",
template: __dirname + "/views/template.ejs",
inject: 'body',
chunks: ['vendor', 'app'],
chunksSortMode: 'manual'
}),
new PreloadWebpackPlugin({
rel: "preload",
include: ["vendor", "app"]
}),
new webpack.optimize.OccurrenceOrderPlugin(),
]
};
真正的问题不是加载脚本的顺序,而是我实际上并没有在 "pre-loading" 它们之后加载脚本:HTMLWebpackPlugin 的 "inject" 行帮助了它,因为它注入了这两行:
<script src="/views/vendor.js"/>
<script src="/views/app.js"/>
在我的index.ejs体内
index.ejs 中加载的脚本顺序不正确。现在是:
<link rel="preload" as="script" href="/views/index.js">
<link rel="preload" as="script" href="/views/vendor.js">
这意味着您的 index.js
将在 vendor.js
之前加载,导致您的应用根本不会出现。首先应加载应用程序的所有依赖项 (vendor.js
),然后才加载 index.js
,因为您需要在执行自定义代码时存在依赖项。所以应该是:
<link rel="preload" as="script" href="/views/vendor.js">
<link rel="preload" as="script" href="/views/index.js">
编辑:
正如我们最终发现的那样,问题不在于脚本的顺序,而是由于脚本实际上并未在 html
中加载。为此,它们需要作为块添加到 HtmlWebpackPlugin
中并注入到 index.html
:
new HtmlWebpackPlugin({
title: "Deals",
filename: __dirname + "/views/index.ejs",
template: __dirname + "/views/template.ejs",
inject: 'body',
chunks: ['vendor', 'index']
})
此外,块 meta
的配置已完全删除。所有其余配置(包括 PreloadWebpackPlugin
)都很好。