webpack-mvc 传统多页面组件化开发详解
最近有一个项目,还是使用的传统MVC模式开发,完全基于jQuery,使用了基于java模板引擎velocity,页面中嵌入了大量java语法,使得前后端分离不彻底,工程打包上线苦不堪言,为实现后端为服务化,前端也得彻底从后端中分离出来。
方案:webpack4+ejs
webpack
- 打包所有的资源
- 打包所以的脚本
- 打包所以的图片
- 打包所以的样式
- 打包所以的表
ejs
高效的JavaScript模板引擎,代替velocity
webpack配置
基本插件
- @babel/core,@babel/preset-env,babel-loader
es6语法转译
- css-loader,style-loader
编译打包css
- node-sass,sass-loader
解析sass
- postcss-loader,autoprefixer
自动给样式增加浏览器前缀
- mini-css-extract-plugin
将css从js中抽离出来为单独文件
- optimize-css-assets-webpack-plugin
压缩css
- uglifyjs-webpack-plugin
压缩js
- ejs-loader
解析ejs模板文件
- html-webpack-plugin
生成html文件
- rimraf
删除文件、文件夹
- watch
监听文件变化
上面是一些要用的插件,具体用法不累述。
入口文件
入口文件长这样(可单一入口,也可多入口):
//多入口 entry:{ pageA:'./src/pageA/index.js', pageB:'./src/pageB/index.js', 'pageC/login':'./src/pageC/login/login.js' }
出口文件:
output:{ filename:'[name].js', path:path.resolve(__dirname,'../dist'), }
filename值中的[name]对应入文件的key值,/分割文件夹。
最后就会在dist文件夹下生产文件:
- dist/pageA/index.js
- dist/pageB/index.js
- dist/pageC/login/login.js
既然是多页面开发,就要有多个入口,每个页面都要有自己对应的js入口,这样我们只需要遍历html文件,然后找到对应的js,处理成entry对象即可
constpath=require('path') constglob=require('glob') constpages=(entries=>{ letentry={},htmlArr=[] //格式化生成入口 entries.forEach((file)=>{ //...../webpack-mvc/src/page/pageA/index.html constfileSplit=file.split('/') constlength=fileSplit.length //页面入口pageA/index.html constfilePath=fileSplit.slice(length-2,length).join('/') //根据html路径找到对应的js路径,js可以和html放在同一文件夹,也可单独放在一个文件夹内,只要能找到 constjsPath=path.resolve(__dirname,`../src/page/${filePath.split('.')[0]}.js`) //_main.ejs页面主题框架,html组件化 pageHtml=path.resolve(__dirname,'../src/_main.ejs') if(!fs.existsSync(jsPath)){ return; } entry['js/'+filePath.split('.')[0]]=jsPath//加js/即表示将打包后的js单独放在一个文件夹内 }) returnentry })(glob(path.resolve(__dirname,'../src/page/*/*.html'),{sync:true}))
上面只是本例的目录结构,根据不同的目录结构,更改路径即可,目的就是得到‘js打包生成路径':‘入口js'映射关系。
html(ejs)组件化
页面框架
1、主体框架src/_main.ejs
<%=htmlWebpackPlugin.options.title%> <%=require('@/common/components/header/header.ejs')()%>