webpack4打包vue前端多页面项目

之前一直用的脚手架,这次自己搭建webpack前端项目,花费了不少心思,于是做个总结。

1.用法

项目结构如下:

project |- bulid <!-- 这个目录是自动生成的--> |- public |- css |- js |- page1.html <!-- 插件生成的html文件--> |- page2.html <!-- 插件生成的html文件--> ... |- public/ <!-- 存放字体、图片、网页模板等静态资源--> |- src <!-- 源码文件夹--> |- components/ |- css/ |- js/ |- page1.js <!-- 每个页面唯一的VUE实例,需绑定到#app--> |- page2.js <!-- 每个页面唯一的VUE实例,需绑定到#app--> ... |- package.json |- package-lock.json |- README.md

public文件夹存放一些静态文件,src文件夹存放源码。每个页面通过一个入口文件(page1.js,page2.js,..)生成vue实例,挂载到插件生成的html文件的#app元素上。

安装依赖

$ npm install

进入开发模式

$ npm run start

浏览器会打开 :3000 ,这时页面一片空白,显示 cannot get几个字。不要慌,在url后面加上 /page1.html ,回车,便可看见我们的页面。 这是因为我把开发服务器的主页设置为 index.html ,而本例中页面为 page1.html,page2.html,因此会显示一片空白。

开发完成了,构建生产版本:

$ npm run build

这会产生一个build/文件夹,里面的文件都经过优化,服务器响应的资源,就是来自于这个文件夹。

2.介绍

2.1 webpack基础配置

我们的开发分为生产环境和开发环境,因此需要有2份webpack的配置文件(可能你会想用env环境变量,然后用3目运算符根据env的值返回不同值。然而这种方法在webpack导出模块的属性中无效,我试过~~~)。这里我们拆分成3个文件,其中 webpack.common.js 是常规的配置,在两种环境下都会用到, webpack.dev.js 和 webpack.prod.js 则是在2种环境下的特有配置。这里用到 webpack-merge 这个包,将公共配置和特有配置进行合成。

webpack.common.js const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const VueLoaderPlugin = require('vue-loader/lib/plugin'); const devMode = process.env.NODE_ENV !=='production'; // 需要被打包入口文件数组 // 数组元素类型 {string|object} // string:将以默认规则生成bundle // object{filename|title|template} 生成的bundle.html的文件名|title标签内容|路径 /public 下的模板文件(需指定文件后缀) const entryList = [ 'page1', 'page2', ]; /** * @param {array} entryList * @param {object} option:可选 要手动配置的内容 */ const createEntry = (list = [], option = {}) => { const obj = {}; list.forEach((item) => { const name = item.filename ? `./js/${item.filename}` : `./js/${item}`; obj[name] = path.resolve(__dirname, './src', `./${item}.js`); }); return Object.assign(obj, option); }; module.exports = { entry: createEntry(entryList), output: { path: path.resolve(__dirname, './build'), }, module: { rules: [ { test: /\.js$/, exclude: /(node_modules|bower_components)/, use: { loader: 'babel-loader', options: { presets: ['@babel/preset-env'], }, }, }, { test: /\.vue$/, use: 'vue-loader', }, { test: /\.(woff|woff2|eot|ttf|otf)$/, use: { loader: 'file-loader', options: { name: 'public/fonts/[name].[ext]', }, }, }, { test: /\.(png|svg|jpg|gif)$/, use: { loader: 'file-loader', options: { name: 'public/images/[name].[ext]', }, }, }, ], }, plugins: createPluginInstance(entryList).concat([ // vue SFCs单文件支持 new VueLoaderPlugin(), ]), };

这里我们没有进行css文件的配置,是因为生产环境下需要优化、提取,所以在另外2个文件分别配置。

webpack.dev.js const webpack = require('webpack'); const path = require('path'); const merge = require('webpack-merge'); const common = require('./webpack.common.js'); module.exports = merge(common, { mode: 'development', devtool: 'inline-source-map', output: { filename: '[name].js', chunkFilename: '[name].js', }, module: { rules: [ { test: /\.(css|less)$/, use: [ 'vue-style-loader', 'css-loader', 'postcss-loader', 'less-loader' ], }, ], }, resolve: { alias: { vue: 'vue/dist/vue.js' } }, });

vue分为开发版本和生产版本,最后一行是根据路径指定使用哪个版本。

webpack.prod.js

const webpack = require('webpack'); const merge = require('webpack-merge'); const CleanWebpackPlugin = require('clean-webpack-plugin'); const MiniCssExtractPlugin = require("mini-css-extract-plugin"); const UglifyJsPlugin = require("uglifyjs-webpack-plugin"); const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin"); const common = require('./webpack.common.js'); module.exports = merge(common, { mode: 'production', output: { filename: '[name].[contenthash].js', chunkFilename: '[name].[contenthash].js', }, resolve: { alias: { vue: 'vue/dist/vue.min.js' } }, module: { rules: [ { test: /\.(css|less)$/, use: [ MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader', 'less-loader' ], }, ], },

在production环境下,我们使用了哈希值便于缓存,以后往生产环境下添加其他资源都会如此。

2.2 解决文件输出目录

我们期待的build文件夹具有如下结构:

build
  |- css/
  |- js/
  |- page1.html
  |- page2.html
  ...

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/b2c45edd280598cac31e0dcabfc2ad5f.html