一、vue-cli3单页搭建方案1、在target文件夹下执行vueui;用于创建vue项目的ui版本界面;2.打开路由器文件夹索引视情况配置路由器模式。它是默认哈希值还是历史记录?ps:个人推荐history模式,因为如果嵌入了app之类的H5页面,有些app可能不允许页面上有'#',hash会使用url上的#进行路由转发。ps:history模式发布到服务器时需要nginx配置。详情请百度。constrouter=newVueRouter({base:'/',mode:'history',//也可以设置为'hash'模式路由})3.在根目录新建vue.config.js,覆盖webpack配置,如下将内容复制到文件中作为初始配置//constwebpack=require('webpack')module.exports={lintOnSave:false,//DisableeslintdevServer:{open:true,//构建完成后自动打开浏览器},configureWebpack:{plugins:[//全局配置node_modules中的模块,无需引入newwebpack.ProvidePlugin({$:"jquery",jQuery:"jquery","windows.jQuery":"jquery"})]},//webpacklinkAPI,用于生成和修改webpack配置chainWebpack:(config)=>{//取消chunks,每个页面只对应一个JS/CSSconfig。optimization.splitChunks({cacheGroups:{}});//配置//.plugin('webpack-bundle-analyzer')//.use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin)},pluginOptions:{}}4.配置好这些之后,当npmrunserve启动项目时,会加载下面两个jsnpmrunserveapp.js:是所有单页第一次渲染必须加载的js。内部融合了framework和js(比如vue、vue-x、vue-router等非异步组件但指的是node_modules中的modules),以及所有页面的commonmoduleabout.js:是每个页面独立的js,这与模块在路由器中的引用方式有关。具体如下:1.ImportHomefrom'../views/Home.vue'是引用页面模板组件的引用方法,不会出现about.js文件,因为属于同步module,当前文件中构建的js会被打包到app.js中。但是随着页面数量的增加,公用的app.js会越来越大。视情况,在app.js大小可以接受的前提下权衡使用;2.constroutes=[{path:'/',name:'Home',//component:Homecomponent:()=>import(/*webpackChunkName:"home"*/'../views/Home.vue')//webpack的神奇注释,将拆分的js命名为home},{path:'/about',name:'About',//路由级代码拆分//这会生成一个单独的块(about.[hash].js)forthisroute//在访问路由时延迟加载。component:()=>import(/*webpackChunkName:"about"*/'../views/About.vue')}]这种引用方式是异步引用模板组件,不会将当前形成的js打包到app中.js,所以不会有任何问题。因为只要不加载相应的页面,就不会加载相应页面的js。对应页面的js会被最独立的js动态导入,就像上图中的about.js,只有进入about页面时才会导入。3、如果在main.js中引入了node_modules包,会直接打包到app.js中,无法转义。ps:最后总结,建议各页面异步引用页面模板。5、如果每个页面都引入了node_mudules,就会有对应的vendors-home.js。如果不引入node_mudules,则每个页面的on-demand组件中不会存在vendor-home.js文件,如下图:6.区分本地、测试、线上环境ps:官网提供了一个解决方案,但它需要为多个环境配置创建配置文件。如果嫌麻烦,就不要用官方的方法。使用如下插件拆分环境:cross-env:https://github.com/kentcdodds/cross-envcnpmicress-env--save-dev//更改node环境变量插件后,在package.json中添加如下三行配置,区分本地、测试、线上环境“scripts”:{"serve":"cross-envNODE_ENV=developmentvue-cli-serviceserve","test":"cross-envNODE_ENV=testvue-cli-servicebuild","build":"cross-envNODE_ENV=productionvue-cli-servicebuild"},在vue.config.js中执行如下代码,打印出当前环境。console.log(process.env.NODE_ENV)在src目录下新建config目录,进入该目录,新建gateway.config.js文件,用于配置不同的环境接口主机。代码如下:gateway.config.js文件内容如下://开发环境地址(npmrunserve)constdevHost={//接口地址域名相关baseApi:'https://abc.com',}//测试环境地址(npmruntest)consttestHost={//接口地址域名RelatedbaseApi:'https://abc.com',}//线上环境地址(npmrunbuild)constproHost={//接口地址域名相关baseApi:'https://abc1.com',}//区分环境选择静态资源地址constenv=process.env.NODE_ENVletexportConfig=''if(env==='production'){exportConfig=proHost}elseif(env==='test'){exportConfig=testHost}else{exportConfig=devHost}exportdefaultexportConfigends:之后只需要在接口接口。发布时区分环境打包。7.谈项目引入第三方插件解决方案ps:原则:移动端单个js大小不超过200k;pc端单个js大小不超过400k;1.vue模块化引入node_modules打包插件:前提是每个页面都是异步加载的,这样做的好处是不会将单个页面的js打包到公共的app.js中。然后在单个js中引入第三方库。但是根据测试:这种模块化引入第三方插件,比CDN模式引入的JS体积至少大2倍,因为webpack内部对每个第三方库进行了二次处理,会增加js音量。平衡js大小的使用。2、cdn方式引入第三方插件:提供这种方式是因为有些库不支持vue,只支持cdn方式引入,比较轻量级。您可以选择该方案以异步cdn方式引入第三方插件。这些方法底部的脚手架示例中有demo;八、项目中常用的打包插件和第三方库1.vuehttps://cn.vuejs.org2.vue-routerhttps://router.vuejs.org3.vue-xhttps://vuex.vuejs.org4.sasshttps://www.sass.hk5.axioshttp://www.axios-js.com/6.normalize.csshttp://necolas.github.io/normalize.css/7.n-zeptohttps://npm.taobao.org/package/n-zepto8.webpack-bundle-analyzerhttps://github.com/webpack-contrib/webpack-bundle-analyzer下面是vue-cli3内置插件-ins(直接在vue.config.js中配置):以下插件可以参考vue-cli3官网配置方法:https://cli.vuejs.org/zh/config/#css-sourcemap8.autoprefixer:自动添加浏览器前缀。(如:-webkit-等)7.url-loader:改变静态资源引用路径7.ProvidePlugin:node_modules中的全局配置模块具体配置方法如下(比较完整的vue.config.js配置):constwebpack=require('webpack')constprocessEnv=process.env.VUE_APP_ENV;//区分环境(值:生产、开发、测试)constisPro=processEnv==='production';//判断生产环境constoutputDir='dist';//输出文件目录(默认dist)constassetsDir='';//配置目录(相对于outputDir)放置生成的静态资源(js,css,img,fonts)//选择区分环境的cdn地址letpublicPath=''//静态资源引用路径letfontPublicPath=''//字体图标引用的cdn路径letimgPublicPath=''//css引用图片cdn路径(c2c/static/img)if(processEnv==='production'){publicPath='https://abc.com/c2c/shop'//官方环境静态资源css、js等cdn路径fontPublicPath=`https://abc.com/c2c/shop/${assetsDir?assetsDir+'/':'/'}fonts`//官方环境字体图标引用的cdn路径imgPublicPath=`https://abc.com/c2c/shop/${assetsDir?assetsDir+'/':'/'}/img`//官方环境css引用图片的cdn路径}elseif(processEnv==='test'){//publicPath='./'//The官方环境静态资源css、js等cdn路径publicPath='https://bcd.com/c2c/shop/dist'//测试环境静态资源css、js等cdn路径'}constdevServerHost='localhost';constdevServerPort='8080';//端口号constdevServerOpen=true;//热启动后自动打开浏览器module.exports={//配置在dist中生成静态cdn资源路径(测试环境为./,正式环境为cdn路径)publicPath:publicPath,//输出文件directory(defaultdist)outputDir,//配置和放置生成的静态资源(js,css,img,fonts)(相对于outputDir)directoryassetsDir,devServer:{host:devServerHost,port:devServerPort,open:devServerOpen,//构建完成后自动打开浏览器//eslint检测影响代码编译,注释不会影响代码编译//overlay:{//warnings:true,//errors:true//}},lintOnSave:processEnv==='发展'?true:false,//开发环境启用eslint,测试和在线编辑代码禁用eslint//webpack配置,key-valueobject配置会合并,当是方法时会重写配置。configureWebpack:config=>{//展开资源,不要把一些资源js等放到包里引用cdn资源让外部s={//'swiper':'swiper',};config.externals=外部;//警告webpack的性能提示config.performance={hints:isPro?'warning':false,//本地开发不显示警告//入口点最大音量maxEntrypointSize:512000,//500kib//生成文件最大音量maxAssetSize:307200,//300kib//只给js文件的性能提示assetFilter(assetFilename){returnassetFilename.endsWith('.js');}};},//webpacklinkAPI,用于生成和修改webpack配置chainWebpack:(config)=>{//取消chunks,每个页面只对应单个JS/CSSconfig.optimization.splitChunks({cacheGroups:{}});//全局配置node_modules中的模块,不需要引入config.plugin('provide').use(webpack.ProvidePlugin,[{$:"n-zepto",Zepto:"n-zepto","window.Zepto":"n-zepto"}]);配置。模块.rule('images').use('url-loader').loader('url-loader').tap(options=>Object.assign(options,{limit:10240,//小于10k,压缩图片=>base64//limit:3000,publicPath:imgPublicPath,name:`[name].[hash:8].[ext]`}))//设置字体字体文件引用的路径config.module.rule('fonts').test(/\.(woff2?|eot|ttf|otf)(\?.*)?$/i).use('url-loader').loader('file-loader').tap(options=>Object.assign(options,{limit:5000,publicPath:fontPublicPath,name:'[name].[hash:8].[ext]'}))//npmrunreport;打印app.js的模块报告,查看各个模块;if(processEnv==='report'){config.plugin('webpack-bundle-analyzer').use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin)}},//css配置处理css:{//是否使用css分离插件ExtractT扩展插件;true:页面css独立拆分,false:页面css打包在同一个package中;extract:true,//启用CSSsourcemaps(默认false),关闭在线,测试并在本地启用sourceMap:isPro?false:true,//css预配置Setter配置项loaderOptions:{sass:{//sass的公共方法和变量需要预编译;prependData:`@import“@/assets/css/global.scss”;@import"@/assets/css/func.scss";`},postcss:{plugins:[//浏览器自动添加前缀require('autoprefixer')({overrideBrowserslist:["Android4.0","iOS7","Chrome>31","ff>31","ie>=8"]}),]}},/**为所有css/预处理器文件启用CSS模块。介绍第三个方ui库,如果js中引用css,必须设置为true,因为如果设置为false,将使用通过js导入的css来启动css模块,以及第三方ui的css类名会追加ha值低的话会出问题。参考文档(vue-cli官网解释):https://cli.vuejs.org/zh/config/#css-requiremoduleextension和https://cli.vuejs.org/zh/guide/css.html#css-modules**/requireModuleExtension:true},//启用多进程处理babelcompileparallel:require('os').cpus().length>1,pwa:{iconPaths:{favicon32:'favicon.ico',favicon16:'favicon.ico',appleTouchIcon:'favicon.ico',maskIcon:'favicon.ico',msTileImage:'favicon.ico'},},//第三方插件配置pluginOptions:{//...}}9.一个基于vue-cli3的单页项目解决方案脚手架,基础配置比较完善:项目脚手架合集包含project-init中的cli-start-spa文件夹,内部readme包含项目详情。
