前言
平时工作中,公司项目没有做前后端分离,用的还是grunt+seajs比较旧的技术,基本是后端主导,前端只负责样式和效果,没办法有更多尝试。不过,前端技术日新月异,不能因为环境而局限自己想折腾的心,于是,在看过《基于webpack的前端工程化开发之多页站点篇》这篇文章之后,开始尝试。
github地址
webpack-multiplepage前端工程化多页面配置
项目依赖
npm init
初始化项目
npm install plugins --save-dev
安装依赖
package.json
依赖声明如下:"devDependencies": {
"babel-core": "^6.26.0", // babel转译核心
"babel-loader": "^7.1.2", // webpack使用转换ES6
"babel-preset-env": "^1.6.1", // 转码规则,按需转译
"clean-webpack-plugin": "^0.1.18", // 清理文件
"copy-webpack-plugin": "^4.5.0", // 复制文件
"css-loader": "^0.28.9", // 将css装载到js
"exports-loader": "^0.7.0", // 模块化,导出指定对象
"extract-text-webpack-plugin": "^3.0.2", // 将css分离成文件
"file-loader": "^1.1.11", // 解析项目中的url引入
"glob": "^7.1.2", // 根据模式匹配获取文件列表的node模块
"html-loader": "^0.5.5", // 解析html文件的url
"html-webpack-plugin": "^2.30.1", // 处理html文件
"node-sass": "^4.7.2", // 编译sass
"sass-loader": "^6.0.7", // 将sass文件编译成css
"script-loader": "^0.7.2", // 全局上下文执行一次 JS 脚本
"style-loader": "^0.20.1", // css插入到页面的style标签
"uglifyjs-webpack-plugin": "^1.1.8", // 压缩js
"url-loader": "^1.0.1", // url-loader封装了file-loader,将小图片生成dataURl
"webpack": "^3.9.1", // webpack核心
"webpack-dev-server": "^2.11.1", // 热更新服务
"webpack-merge": "^4.1.1" // 合并配置
}
npm run dev
执行开发环境,点击进入view
文件夹
npm run build
执行打包发布
目录结构
- website |
项目目录有个局限性,就是开发目录里js
中固定需要page
文件夹放置页面级的js逻辑,与view
中的.html
文件一一对应。
开发
在src/js/page目录下建立index.js文件,在src/view目录下建立index.html文件。入口js和模板文件名对应。
index.js文件如下(这里已默认引入zepto
,可直接使用$
):
require("scss/variable.scss"); |
index.html 内容如下:
<html>
<head>
<meta charset="UTF-8" />
<title>测试首页</title>
<!--
描述:head中无需再引入css以及facicon,webpack将根据入口JS文件的要求自动实现按需加载或者生成style标签
-->
</head>
<body>
<div class="gb-body"></div>
<!--
描述:body中同样无需单独引入JS文件,webpack会根据入口JS文件自动实现按需加载或者生成script标签,还可以生成对应的hash值
-->
</body>
</html>
webpack配置
webpack配置base.js
如下:
const path = require('path') // 引入node模块,获取路径 |
webpack开发配置dev.js
如下:
const webpack = require('webpack') // webpack |
webpack开发配置pro.js
如下:
const path = require('path') |
根据模式匹配获取文件列表
结合《基于webpack的前端工程化开发之多页站点篇(一)》和《基于webpack的前端工程化开发之多页站点篇(二)》这两篇文章,应该很容易完成配置,但是我也发现一个问题,就是在view
配置多级目录的时候类似view/question/question.html
,打包配置会出问题,就仅局限于当前目录。
于是参考了kisnows 抹桥的Spart项目webpack配置,对入口和html生成配置做了调整。
getEntry.js
如下:const glob = require('glob')
const path = require('path')
const cwd = process.cwd()
module.exports = function(jsPath){
const entrys = {}
const entryFiles = glob.sync(jsPath)
const reg = /src\/(\S+)$/
const fileReg = /src\/js\/(\S+).js$/
entryFiles.forEach((v) => {
const pathname = v.match(reg)[1]
const filename = v.match(fileReg)[1]
entrys[filename] = `./src/${pathname}`
})
return entrys
}
getEntry.js
输出结果如下(举个栗子):{
'page/about': './src/js/page/about.js',
'page/index': './src/js/page/index.js',
'page/question/question': './src/js/page/question/question.js'
}
getHtml.js
如下:const glob = require('glob')
const path = require('path')
const cwd = process.cwd()
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = function (htmlPath){
const pluginList = []
const htmlFileList = glob.sync(htmlPath)
const reg = /src\/(\S+)$/
const fileReg = /src\/view\/(\S+).html$/
htmlFileList.forEach((v)=>{
const pathname = v.match(reg)[1]
const filename = path.basename(v, path.extname(v))
const shortname = v.match(fileReg)[1]
pluginList.push(
new HtmlWebpackPlugin({
filename: `${pathname}`,
template: `./src/${pathname}`,
inject: 'body',
chunks: ['vendors', `page/${shortname}`],
hash: false,
minify: process.env.NODE_ENV !== 'production' ? false : {
removeAttributeQuotes: true,
removeComments: true,
collapseWhitespace: true,
html5: true,
minifyCSS: true
}
})
)
})
return pluginList
}
getHtml.js
输出结果如下(举个栗子):[
{
filename: 'view/about.html',
template: './src/view/about.html',
inject: 'body',
chunks: [ 'page/vendors', 'page/about' ],
hash: false,
minify: false
},
{
filename: 'view/index.html',
template: './src/view/index.html',
inject: 'body',
chunks: [ 'page/vendors', 'page/index' ],
hash: false,
minify: false
},
{
filename: 'view/question/question.html',
template: './src/view/question/question.html',
inject: 'body',
chunks: [ 'page/vendors', 'page/question/question' ],
hash: false,
minify: false
}
]
如何在 webpack 中引入未模块化的库,如 Zepto
解决方法:
$ npm i -D script-loader exports-loader |
引入script-loader与exports-loader,然后参考以上的配置
NodeJs中process.cwd()与__dirname的区别
process.cwd()
是当前执行node命令时候的文件夹地址 ——工作目录,就是说 process.cwd()
返回的是当前Node.js进程执行时的工作目录
__dirname
是被执行的js文件的地址 ——文件所在目录,等同于 __filename
的 path.dirname()
参考
结语
其实在配置的过程中,有考虑到一个问题,就是后端童鞋不一定会用你这一套东西,就好像@抹桥说的那样,感觉这是为了用 webpack 而用 webpack 的节奏,还不如直接用gulp来的方便。可能确实也可能如此,但后面又想一想,思路通了就做一下吧,不能总是半途而废,于是就有了这篇文章。
配置的时候,参照了很多文章,自身水平有限,如有冒犯,请通知我!
谢谢您的品读,此处抛砖引玉,希望大家共同探讨学习。