webpack多页面方案
上一篇总结了webpack的配置,其实配置还是相对容易的,因为只要根据需要照搬选项就好了,但是只写配置项那最终打包出来的结果就是一个html和一个js,如果页面多了那肯定是不行的,所以就需要想办法拆分代码,我所知道的拆分代码方式大概有2种:1.使用react-loadable + import();2.entry的对象写法和html-webpack-plugin的chunks选项;
参考文章比较多,没怎么记录
方案1
react-loadable + import()
这个方案需要@babel/plugin-syntax-dynamic-import的支持,记得修改babelrc。一般用这个方案的话是要用react-router来写一个单页应用,模板加载一个入口js,入口js里把页面路由写好,每个页面作为一个组件,然后写一个类似这样的结构
import Loadable from 'react-loadable';
const routeArr = [
{
path: '/page1',
component: Loadable({
loader: () =>
import(
/* webpackChunkName: "page1" */
'./page1'
),
loading: <div>loading...</div>
})
},
{
path: '/page2',
component: Loadable({
loader: () =>
import(
/* webpackChunkName: "page2" */
'./page2'
),
loading: <div>loading...</div>
})
}
]
// 其他部分省略了
render() {
return (
<Switch> // 用Switch而不是Router可以保证只匹配到一个路径
{routeArr.map((v, k) => {
return <Route key={k} path={`/${v.path}`} component={v.component} />;
})}
</Switch>
);
}
这个方案的问题在于,/* webpackChunkName: "page2" */
这个注释,这个注释不加,动态import是不生效的,即使生效,也不能通过写一个循环来把所有的页面组件都循环import,也就是说,每添加一个页面组件,就要自己往routeArr里加一段代码,当然可以通过别的方式来生成这个routeArr,比如写文件方式,根本问题就是routeArr要以硬编码形式存在,而不能是这样的
const routeArr = ['page1', 'page2'].map((v, k)=>{
return {
path: `/${v}`,
component: Loadable({
loader: () =>
import(`./${v}`),
loading: <div>loading...</div>
})
};
})
这个方案的优点在于,1.不需要多个html模板,是个标准的单页应用;2.不需要多个html-webpack-plugin实例;3.工程路径可以随意,只要写到路由数组里的时候自己确定是对的就可以,不需要统一,但是作为一个工程当然是统一为好;4.写一些页面共有的组件,比如菜单,顶部导航等比较简单
方案2
webpack的入口配置这样写
entry: {
page1:"./src/page1.js",
page2:"./src/page2.js"
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name]_[contenthash].js' // 这里如果用hash,每个文件的hash是一样的,所以要用内容hash
}
html-webpack-plugin插件这样来写
const HtmlWebpackPlugin = require("html-webpack-plugin");
plugins: [
new HtmlWebpackPlugin({
filename: "page1.html",
template: "./src/page1.html",}),
chunks: ["page1"]
}),
new HtmlWebpackPlugin({
filename: "page2.html",
template: "./src/page2.html",}),
chunks: ["page2"]
})
]
注意创建HtmlWebpackPlugin实例时的chunks选项,这个选项如果不写,默认会把entry里生成的所有文件全部注入到每个HtmlWebpackPlugin实例里去,为了出这个坑我看了好多篇文章
这个方案的优点在于,不用每次手写添加的页面的名称和路由(对比方案1),只要按照约定的工程目录创建页面,就可以通过遍历目录生成入口和HtmlWebpackPlugin实例来打包,缺点是页面多的情况下HtmlWebpackPlugin实例也很多,应该会影响性能,并且如果要写一些页面上都有的组件(比如菜单和导航),就要在每个页面里自己引用
方案3
如果觉得多个html-webpack-plugin实例的方式不靠谱,可以把方案2改改,还是配多个entry,工程目录也一样,然后自己写一个路由,根据当前加载的url来判断加载哪个js,这样其实就和方案1很类似了,这个路由写在服务端会比较好,可以提前设置好js的链接,也可以实现页面权限之类的需求
上一篇: webpack--概念2--入口起点
下一篇: oracle数据泵导入导出