1、现状
继上次完成Vue.js实战——框架搭建_2,发现自动生成的框架配置(包括编译、打包、调试相关的)文件过多(见下图所示),既分散也不好理解,所以当时也没有去解读各个配置的含义。
今天就来精简Vue.js项目使用的webpack配置,使之简单易懂,降低出错的成本。
2、目标
把webpack配置文件精简成一个单独的文件,去掉冗余且不太使用的配置,让大伙能够享受框架搭建的简约之美。
3、优化过程
3.1 多个配置文件优化成1个配置文件
- 重新新建一个geolocation_2项目文件夹,我们仅需要geolocation_1中的业务内容页面(根路径下的index.html文件以及src下的所有内容)。
- 按照下述目录结构对代码进行整理(参考了网友整理的目录结构):
|app
|--webpack.config.js //webpack入口配置
|--package.json //依赖json(基本上不需要管,只有额外引库时,可手动修改此问文件引入,也可shell中执行npm命令引入)
|--|--dist //打包之后根目录,我们不用管
|--|--src //源码
|--|--|--commons //非业务的核心公共组件(基础)
|--|--|--components //业务相关的组件(可引用commons的组件)
|--|--|--js //页面或者业务相关的js(非js库)
|--|--|--lib //js库(部分js库组件可能会包含Vue文件)
|--|--|--pages //多页面,包括html页面,vue页面
|--|--|--assets //静态资源,如图片等
对应此项目geolocation_2的目录结构为:
3. 框架搭建阶段,最重要的是要把基础配置搞好,本人配置的webpack.config.js如下:
const path = require("path"); //node路径处理模块
const webpack = require('webpack'); //webpack必要条件
const HtmlWebpackPlugin = require('html-webpack-plugin'); //多页面生成视图插件
const CleanWebpackPlugin = require('clean-webpack-plugin'); //清除工程目录插件
const CompressionPlugin = require('compression-webpack-plugin'); //压缩插件
module.exports = {
//对象形式entry
entry: {
index: './src/js/main.js', //vue文件绑定的js文件,有多个写多个
},
output: {
path: path.resolve(__dirname, './dist'), //打包之后工程根目录
publicPath: '/static/', //html资源对应的server目录
filename: '[name].[hash].js', //每个页面对应的js文件
},
module: {
rules: [{
test: /\.css$/,
use: ["vue-style-loader", "css-loader"]
},
{
test: /\.vue$/, //.vue文件处理
loader: 'vue-loader',
options: {
loaders: {}
}
},
{
test: /\.js$/, //es6转es5处理
loader: 'babel-loader',
exclude: /node_modules/
},
{
test: /\.(png|jpg|gif|svg)$/,
loader: "file-loader",
options: {
name: "[name].[ext]"
}
},
{
test: /\.html$/, //html打包,可有可无
loader: 'html-loader',
options: {}
}
]
},
resolve: {
alias: {
vue$: "vue/dist/vue.esm.js"
},
extensions: ["*", ".js", ".vue", ".json"]
},
plugins: [
new CleanWebpackPlugin(["dist"]), //构建dist之前清除老版目录
new HtmlWebpackPlugin({ //一个html文件,有多个复写多个HtmlWebpackPlugin
filename: "index.html",
template: "./src/pages/index.html",
inject: true,
chunks: ["index"]
}),
],
devServer: { //开发模式下使用的配置参数
historyApiFallback: true,
noInfo: true,
overlay: true,
contentBase: path.resolve(__dirname, "./src/assets") //本地调试时,图片等资源对应的根路径
},
devtool: "#eval-source-map"
};
if (process.env.NODE_ENV === "production") { //生产环境,启用兼容和js压缩处理
module.exports.devtool = "#source-map";
// http://vue-loader.vuejs.org/en/workflow/production.html
module.exports.plugins = (module.exports.plugins || []).concat([
new webpack.DefinePlugin({
"process.env": {
NODE_ENV: '"production"'
}
}),
new webpack.optimize.UglifyJsPlugin({
sourceMap: true,
compress: {
warnings: false
}
}),
new webpack.LoaderOptionsPlugin({
minimize: true
}),
new CompressionPlugin({
filename: "[path].gz[query]",
algorithm: "gzip",
test: /\.js$/,
threshold: 1024,
minRatio: 0.8,
})
]);
};
//DEV模式时,指定公共路径为当前路径
if (process.env.PLATFORM == "DEV") {
module.exports.output.publicPath = "";
}
4. package.json文件配置如下(默认dependencies下什么依赖也不加,只在devDependencies上加上如下配置,这样可以做到业务组件和vue本身依赖的基础组件的分离,同时有效控制项目最后打出的文件的大小):
{
"name": "justinsoft",
"description": "A Vue.js project",
"version": "1.0.0",
"author": "woollay@163.com",
"license": "MIT",
"private": true,
"scripts": {
"dev": "cross-env NODE_ENV=development PLATFORM=DEV webpack-dev-server --open --hot",
"build": "cross-env NODE_ENV=production webpack --progress --hide-modules"
},
"dependencies": {},
"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 8"
],
"devDependencies": {
"babel-core": "^6.26.3",
"babel-loader": "^7.1.5",
"babel-preset-env": "^1.7.0",
"babel-preset-stage-3": "^6.24.1",
"clean-webpack-plugin": "^0.1.19",
"compression-webpack-plugin": "^1.1.12",
"cross-env": "^5.0.5",
"css-loader": "^0.28.11",
"file-loader": "^1.1.11",
"html-loader": "^0.5.5",
"html-webpack-plugin": "^3.2.0",
"vue": "^2.5.11",
"vue-html-loader": "^1.2.4",
"vue-i18n": "^8.0.0",
"vue-loader": "^13.7.3",
"vue-style-loader": "^4.1.2",
"vue-template-compiler": "^2.5.11",
"webpack": "^3.12.0",
"webpack-dev-server": "^2.9.1",
"babel-preset-es2015": "^6.24.1"
}
}
5. 命令行进入geolocation_2目录,通过执行shell命令编译命令:npm run build,会出现“Unexpected token: punc (() ”报错,原因是因为需要兼容ES5语法,解决方案是:在当前根路径下新建一个.babelrc文件,内容如下:
{
"presets": ["es2015"]
}
6. 按照步骤5解决所有的组件报错依赖问题。如果有什么问题解决不了,可以在网上搜下报错的解决方案,也欢迎留言交流。
7. 完成上述步骤后,需要相应的调整vue/js文件中相互引用的路径错误问题,此处我就不一一讲解了。大家可以从这里查看修改好了之后的Demo源码。
3.2 解决Dev模式下本地相对图片路径无法识别的问题
在根路径下执行npm run dev时,会动态生成一个html文件和相对引用路径,如上图webpack.config.js中的publicPath路径为:"/static/"。但是在开发模式下,我们图片的相对路径无法加上该虚拟路径,所以:
1)要在devServer中明确指定图片资源的相对路径(见webpack.config.js中的contentBase参数配置);
2)要把dev的publicPath重置为当前的根路径(见webpack.config.js最后一段配置,注意当前根路径是"",而不是"./")
3.3 按照新架构重新发布Demo
1. 大家可以从这里下载github管理的Vue.js实战——精简webpack配置_3源码。
2.运行npm run dev后的效果图如下:
4、总结
1. 从头开始搭建一个项目的基础框架,特别劳神费力,但是对于初学者尤为重要,因为这样会培养对框架整体的认知,大体掌握平台框架和各个组件搭配的方方面面,然后可以再深入一一学习,各个击破;
2.后续我会基于此精简的框架,进一步讲解如何通过前端编程来实现多媒体交互功能、组件抽象以及与各大平台对接方面的经验,只为初心。
上一篇:Vue.js实战——框架搭建_2 下一篇:Vue.js实战——获取浏览器经纬度的各种坑_4
6、参考资料:
[1]https://blog.csdn.net/wbiokr/article/details/77170792
[2]https://blog.csdn.net/wbiokr/article/details/77171010
[3]https://www.cnblogs.com/toward-the-sun/p/6147324.html?utm_source=itdadao&utm_medium=referral
[4]https://segmentfault.com/a/1190000012383015
[5]https://www.cnblogs.com/zourong/p/5943224.html
[6]https://blog.csdn.net/goodboy1739/article/details/78547042?locationNum=7&fps=1