内容简介:多页面,首先最重要的就是处理多个 html 模板和对应的多个入口文件。在项目根目录创建一个然后在
- 最近有一个项目,考虑到要进行 SEO,所以要做成多页面应用。为了保证开发速度和开发效率,所以决定使用 webpack 做一套模块化配置方案。
- 下面主要针对一些重要的点提供思路,并不作详解。完整的代码,我会放在 github( 项目地址 )上供大家参考,如果有优化的地方,请在评论区指点出来,。
目录
|-- build webpack 配置 | |-- utils.js 处理 webpack 配置的公共方法 | |-- webpack.base.conf.js 公共配置 | |-- webpack.dev.conf.js 开发环境配置 | |-- webapck.prod.conf.js 生产环境配置 | |-- webpack.rules.conf.js 文件处理规则 |-- dist 存放变异后文件 |-- | |-- src 源文件 | |-- assets | |-- pages | | |-- index 首页 | | | |-- index.html 首页模板 | | | |-- index.js 首页入口文件 | htmlarrary.js 页面配置文件
多页面
多页面,首先最重要的就是处理多个 html 模板和对应的多个入口文件。
html 模板
在项目根目录创建一个 htmlarrary.js
,用来存储页面配置:
// htmlarrary.js module.exports = [ { _html: 'index', title: '首页', chunks: ['index', 'manifest', 'vendors'] // 页面用到的vendor模块 }, { _html: 'login', title: '登录', chunks: ['login'] } ]
然后在 /build/utils.js
创建 getHtmlArray
方法,用来自动生成多个模板的配置:
// /build/utils.js const HtmlWebpackPlugin = require('html-webpack-plugin') const htmlArray = require('../htmlarray.js') exports.getHtmlArray = function (moduleExportsPlugins) { // 根据模板配置生成 HtmlWebpackPlugin 需要的配置 const getHtmlConfig = function (name, chunks, title) { return { template: `./src/pages/${name}/index.html`, filename: `./${name}.html`, favicon: './src/assets/images/public/favicon.ico', title, inject: true, hash: true, // 开启hash chunks, // 页面要引入的包 minify: process.env.NODE_ENV === 'development' ? false : { removeComments: true, // 移除HTML中的注释 collapseWhitespace: true, // 折叠空白区域 也就是压缩代码 removeAttributeQuotes: true, // 去除属性引用 }, }; }; // 循环创建模板配置 htmlArray.forEach((element) => { const { _html, chunks, title } = element moduleExportsPlugins.push(new HtmlWebpackPlugin(getHtmlConfig(_html, chunks, title))) }) }
在 webpack.base.conf.js
中通过 getHtmlArray
添加多页面引擎配置:
const { getHtmlArray } = require('./utils.js') module.exports = { // ... 相关配置 } getHtmlArray(module.exports.plugins)
入口文件
在 /build/utils.js
创建 getEntry
方法,用来自动生成入口文件的配置:
// /build/utils.js const glob = require('glob') exports.getEntry = function () { const entry = {} // 读取src目录所有page入口 glob.sync('./src/pages/*/*.js').forEach((name) => { const start = name.indexOf('src/') + 4; const end = name.length - 3; const eArr = []; const n = name.slice(start, end).split('/')[1]; eArr.push(name); eArr.push('@babel/polyfill'); // 引入这个,是为了用async await,一些IE不支持的属性能够受支持,兼容IE浏览器用的 entry[n] = eArr; }) return entry; }
在 webpack.base.conf.js
中通过 getEntry
添加多入口配置:
// webpack.base.conf.js const { getEntry } = require('./utils.js') module.exports = { entry: getEntry(), }
JS
JS 方面,我们一般有以下需求:
- eslint 错误提醒;
- ts-loader 解析 typescript 语法;
- babel-loader 解析 ES6 语法。
针对以上需求,我们来配置一下子 rules,并且做一下延伸:
// webpack.rules.conf.js module.exports = [ { test: /\.(js|ts)$/, exclude: /node_modules/, use: [ { loader: 'babel-loader', options: { presets: [ ['@babel/preset-env', { useBuiltIns: 'usage', targets: { chrome: '58', ie: '8' }, corejs: 2 }] ] } }, { loader: 'ts-loader' }, { loader: 'eslint-loader', options: { cache: true // 优化打包速度 } } ] } ]
在生产环境,我们需要对 js 文件进行压缩,公共代码抽离,所以还需要在 webpack.prod.conf.js
中这样去优化一下:
// webpack.prod.conf.js cconst merge = require('webpack-merge') const UglifyJsPlugin = require('uglifyjs-webpack-plugin') const baseConfig = require('./webpack.base.conf.js') const prodConfig = { optimization: { minimizer: [ // 会导致 sourcemap 消失 new UglifyJsPlugin({ uglifyOptions: ({ compress: false }) }), new OptimizeCSSAssetsPlugin({}) ], splitChunks: { chunks: 'all', cacheGroups: { vendors: { // 抽离第三方插件 test: /[\\/]node_modules[\\/]/, // 指定是node_modules下的第三方包 name: 'vendors', priority: -10 // 抽取优先级 }, utilCommon: { // 抽离自定义 name: 'common', minSize: 0, // 将引用模块分离成新代码文件的最小体积 minChunks: 2, // 表示将引用模块如不同文件引用了多少次,才能分离生成新chunk priority: -20 } } }, // optimization.runtimeChunk 就是告诉 webpack 是否要把这部分单独打包出来,来优化缓存问题 runtimeChunk: { name: 'manifest' } } } module.exports = merge(baseConfig, prodConfig)
CSS
CSS 方面,我们一般有以下需求:
- postcss-loader 安装 autoprefixer 插件,自动进行兼容性处理;
- sass-loader 解析 sass 语法;
- MiniCssExtractPlugin 进行 css 压缩。
针对以上需求,我们来配置一下子 rules,并且做一下延伸:
// webpack.rules.conf.js const MiniCssExtractPlugin = require('mini-css-extract-plugin') module.exports = [ { test: /\.scss$/i, use: [ Object.assign( // 生产环境压缩 css 需要使用 MiniCssExtractPlugin.loader 代替 style-loader { loader: process.env.NODE_ENV === 'production' ? MiniCssExtractPlugin.loader : 'style-loader' }, // 解决编译后 css 图片不能正常显示的问题 process.env.NODE_ENV === 'production' ? { options: { publicPath: '../' } } : {} ), 'css-loader', 'sass-loader', 'postcss-loader' ] } ]
在生产环境,我们需要对 css 文件进行压缩,所以还需要在 webpack.prod.conf.js
中这样去优化一下:
// webpack.prod.conf.js cconst merge = require('webpack-merge') const MiniCssExtractPlugin = require('mini-css-extract-plugin') const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin') const baseConfig = require('./webpack.base.conf.js') const prodConfig = { optimization: { minimizer: [ new OptimizeCSSAssetsPlugin({}) ], }, plugins: [ new MiniCssExtractPlugin({ filename: 'css/[name].[contenthash:8].css', chunkFileName: '[id].[contenthash:8].css' }), ] } module.exports = merge(baseConfig, prodConfig)
images
images 方面,我们一般有以下需求:
- css 和 js 中的图片可以被解析;
- html 中 img 标签的图片可以被解析。
针对以上需求,我们来配置一下子 rules,并且做一下延伸:
// webpack.rules.conf.js const MiniCssExtractPlugin = require('mini-css-extract-plugin') module.exports = [ { test: /\.html$/, use: [ // 如果 img 标签的 src 为空的话,就报错 xxxHTMLLINKxxx0. { loader: 'html-loader', } ] }, { test: /\.(png|jpg|gif|ico)$/, use: [ { loader: 'url-loader', options: { name: '[name].[hash:8].[ext]', limit: 30000, outputPath: './images' } } ] } ]
其他
devserver 和 热更新
// webpack.dev.conf.js const devConfig = { devServer: { open: true, host: '0.0.0.0', port: 2000, useLocalIp: true, hot: true }, plugins: [ new webpack.HotModuleReplacementPlugin() ] }
这样智能启动 css 热更新,如果需要 js 热更新,需要添加一段代码,请自行查找 官网文档 。
报错
- 如果 img 标签的 src 为空的话,就报错 xxxHTMLLINKxxx0.
-
如果报错:
TS2688: Cannot find type definition file for 'unist'.
说明需要安装依赖@types/unist
,其他类似报错一样,这是typescript@2.0
更换 types 支持方式导致的报错。 -
编译后 css 图片路径错误,根据是否是生产环境来动态添加
publicPath
,。
以上所述就是小编给大家介绍的《webpack 配置多页面应用的一次尝试》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
断点:互联网进化启示录
[美]杰夫·斯蒂贝尔 / 师蓉 / 中国人民大学出版社有限公司 / 2014-11-1 / CNY 49.00
一部神经学、生物学与互联网技术大融合的互联网进化史诗巨著。 我们正置身网络革命中。互联网的每一丝变化都与你我息息相关。当科技变得无处不在时,它就会改变你我。在《断点》一书中,大脑科学家和企业家杰夫·斯蒂贝尔将带领读者来到大脑、生物与技术的交汇处,向读者展示生物学和神经学是如何与互联网技术发生联系的;我们是如何通过生物学上的前车之鉴,来预测互联网的发展的;互联网在经历增长、断点和平衡后又会发生......一起来看看 《断点:互联网进化启示录》 这本书的介绍吧!