上一篇文章主要介绍了我对这个项目的技术选型,这篇文章要上点干货啦,主要介绍项目开发环境的搭建,包含以下几个部分。
- 项目目录结构设计
- node版本和npm包选择与安装
- webpack配置
- 启动本地开发服务
项目目录结构设计
合理的目录结构能让开发人员非常清楚地知道各模块的存放位置,方便开发和维护。此项目我设计为多页面入口结构,分为3个主要部分:
- app/,存放nodejs服务相关代码;
- static/,存放客户端源代码;
- dist-xxx/, 存放客户端编译后可运行代码;
其他目录和配置都是为了服务以上三部分而制定的,具体如下:
app/ //node服务相关
controllers/ //数据请求
home_api.js
routes/ //路由配置
views/ //页面模板
app.js //服务入口
bin/ //服务启动
www
build/ //构建配置
webpack.config.js
config/ //项目全局配置
dist-myproject/ //编译后可运行代码
static/ //客户端源码
assets/ //公共资源
common/ //公共js模块
modules/ //业务模块
shop/
index.js //入口js
shop.html //入口页面模板
package.json
myproject-front.json //pm2启动配置
node版本和npm包选择与安装
nodejs 版本我选择的是10.15.3,也是我们现在项目在用的版本,原生就支持es7 的 async await语法,相对更稳定些,你也可以选择更高的版本,注意选择长期支持的稳定版本即可。
npm包主要是结合项目中使用到的,按需安装即可,这个项目主要围绕着三部分安装,分别是:koajs,vuejs,webpack ,具体如下:
{
"name": "myproject",
"version": "1.0.0",
"type": "nodejs",
"description": "myproject for koa",
"main": "./app/app.js",
"scripts": {
"build": "webpack --config ./build/webpack.prod.config.js",
"build-dev": "webpack --config ./build/webpack.dev.config.js",
"start": "concurrently \"npm run webpack-start\" \"npm run start\""
},
"keywords": [
"myproject"
],
"author": "luorh",
"license": "ISC",
"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 8"
],
"dependencies": {
"@koa/router": "9.4.0",
"@vant/touch-emulator": "^1.2.0",
"art-template": "^4.13.2",
"axios": "^0.19.2",
"core-js": "^3.6.5",
"debug": "^3.1.0",
"fastclick": "1.0.6",
"fs-extra": "^9.0.1",
"ip": "^1.1.5",
"koa": "2.13.0",
"koa-art-template": "1.1.1",
"koa-bodyparser": "4.3.0",
"koa-csrf": "^3.0.8",
"koa-helmet": "^5.2.0",
"koa-logger": "^3.2.0",
"koa-onerror": "^4.1.0",
"koa-session": "^6.0.0",
"koa-views": "^6.3.0",
"lodash": "^4.17.10",
"log4js": "^2.7.0",
"pm2-intercom": "^1.0.0",
"qs": "6.5.1",
"vant": "^2.10.2",
"vue": "2.6.11",
"vue-lazyload": "1.2.2",
"vue-progressbar": "^0.7.5",
"vue-router": "3.4.3",
"vuex": "3.5.1"
},
"devDependencies": {
"@babel/core": "^7.11.1",
"@babel/plugin-proposal-class-properties": "^7.10.4",
"@babel/plugin-transform-runtime": "^7.11.0",
"@babel/preset-env": "^7.11.0",
"@babel/preset-typescript": "^7.10.4",
"@babel/runtime": "^7.11.2",
"babel-loader": "^8.1.0",
"babel-plugin-import": "^1.13.0",
"concurrently": "^5.3.0",
"css-loader": "^3.6.0",
"file-loader": "^6.0.0",
"friendly-errors-webpack-plugin": "^1.6.1",
"glob": "^7.1.2",
"gulp": "^3.9.1",
"html-webpack-plugin": "^4.3.0",
"html-webpack-tags-plugin": "^2.0.17",
"mini-css-extract-plugin": "0.8.0",
"nodemon": "^2.0.4",
"optimize-css-assets-webpack-plugin": "^5.0.3",
"postcss-css-variables": "^0.17.0",
"postcss-cssnext": "^3.1.0",
"postcss-import": "^12.0.1",
"postcss-loader": "^3.0.0",
"postcss-modules": "^1.1.0",
"postcss-preset-env": "^6.7.0",
"postcss-pxtorem": "^5.1.1",
"postcss-safe-parser": "^4.0.2",
"postcss-url": "^8.0.0",
"style-loader": "^1.2.1",
"terser-webpack-plugin": "^4.0.0",
"url-loader": "^4.1.0",
"vue-loader": "^15.9.3",
"vue-template-compiler": "^2.6.11",
"webpack": "^4.44.0",
"webpack-bundle-analyzer": "^3.8.0",
"webpack-cli": "^3.3.12",
"webpack-dev-server": "^3.11.0",
"webpack-merge": "^5.1.1"
}
}
webpack配置
在这个项目中代码的构建打包全部使用webpack搞定,舍弃了以往的gulp+webpack的组合方式,具体分以下3个配置文件:
webpack.base.config.js //基础配置
webpack.prod.config.js //生产环境配置
webpack.dev.config.js //开发环境debug配置
上面提到,我们这个项目设计为多页面入口,为此我写了一段脚本来负责扫描项目中的页面模块,生成入口文件的json对象,具体如下:
const SRC_PATH = path.resolve(__dirname, '../static/modules/'); //模块目录
const moduleNames = fs.readdirSync(SRC_PATH) //获取模块数组
const entryJs = {}, //入口js对象
pluginTpls = [];//入口html模板,配合HtmlWebpackPlugin使用
moduleNames.forEach(module => {
// 收集入口文件
if (fs.existsSync(path.join(SRC_PATH, `/${module}/index.js`))) {
entryJs[module] = path.join(SRC_PATH, `/${module}/index.js`)
// 收集html模板 生成HtmlWebpackPlugin 配置文件
if (fs.existsSync(path.join(SRC_PATH, `/${module}/${module}.html`))) {
pluginTpls.push(new HtmlWebpackPlugin(Object.assign({
template: path.join(SRC_PATH, `/${module}/${module}.html`),
filename: `${module}/index.html`,
chunks: [module],
}, isEnvProduction
? {
minify: {
removeComments: true, // 移除注释
collapseWhitespace: true, // 移除标签内的空格 SCRIPT, STYLE, PRE or TEXTAREA.除外
removeRedundantAttributes: true,
useShortDoctype: true,
removeEmptyAttributes: true, // 移除标签空属性
removeStyleLinkTypeAttributes: true,
keepClosingSlash: true,
minifyJS: true,
minifyCSS: true,
minifyURLs: true,
},
}
: undefined)))
} else {
throw ('\033[31m错误:模块 [' + module + '] 未给出正确的html模板 '+module+'.html\033[0m');
}
} else {
console.log('\033[33m警告:模块 [' + module + '] 未给出正确的入口文件 index.js\033[0m')
}
})
结合上述代码再细讲一下,该项目的 static/modules/目录下存放着每个业务的功能模块,可以是一个独立页面,也可以是一个vue +router 结构的 spa页面集,这里有个模块创建规范:每个模块的文件夹名称要求是英文小写,如:shop,如果需要多个单词拼接,是以 – 杠链接,如:order-list,在模块文件夹的根目录下必须有两个文件,分别是:index.js和对应模块名称的xxx.html模板文件,如:shop.html。了解这些后再去看上述代码应该会更清晰一些。
还有,webpack配置中还有 postcss(css预编译),webpack-dev-server(本地页面预览和热重启),具体完整配置我会在这系列文章完结后将代码上传到github供大家查阅。
启动本地开发服务
最后,所有环境配置都完成后 ,将配置命令集成在 package.json 的 scripts内,具体是:
"build": "webpack --config ./build/webpack.prod.config.js", //构建生产环境代码
"build-dev": "webpack --config ./build/webpack.dev.config.js", //构建未压缩的debug代码
"start": "concurrently \"npm run webpack-start\" \"npm run start\"" //启动本地开发服务
前两个命令好理解,根据需要执行就好,npm run start 内通过 concurrently 开启了两个进程分别启动了 webpack-dev-server(本地页面预览)和 nodejs api服务,其目的是为了方便你在即改了node层的代码又改了客户端的js代码时,可以进行同时热重启,很方便地进行调试。
小结
这一篇主要介绍了目录结构设计,node版本和npm包的选择和webpack 的主要配置,文中没有细讲基础类的知识点,如,node如何安装,webpack基本配置等,因为那些直接去官网按文档执行就好,我主要想表述的是如何将他们优雅的组织起来,以更好的服务项目,以达到高效且稳定。
后面的几篇文章我会继续分享在实际业务功能开发中遇到的一些问题,比如,如何兼容小程序,原生app,H5浏览器兼容等等,感谢阅读!
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://itzsg.com/10293.html