利用 Webpack 实现小程序多项目管理 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a Javascript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
Javascript 权威指南第 5 版
Closure: The Definitive Guide
kaolalicai
V2EX    Javascript

利用 Webpack 实现小程序多项目管理

  •  
  •   kaolalicai 2019-04-18 11:32:33 +08:00 3380 次点击
    这是一个创建于 2447 天前的主题,其中的信息可能已经有所发展或是发生改变。

    故事是这样开始的

    前端开发小哥 Bingo 接到了产品小姐姐的需求,要上线多个小程序.

    码畜小哥开始架构

    • 小程序杂,放一个项目方便管理
    • 小程序多,代码要能够复用
    • 团队开发,代码风格要统一

    码畜小哥开始建项目

    这是单个小程序的基本目录结构,没问题

    图片描述

    当一个项目有多个小程序的时候,好像也没问题

    图片描述

    当多个小程序都用到同一个组件 com3 时,小哥发现代码没法复用,需要复制黏贴

    图片描述

    思考了一下,那么把组件目录移到外面,这样不就可以复用了吗?

    图片描述

    感觉很好,小哥这时在微信开发者工具打开 demo1,发现报错了

    图片描述

    原来小程序是以当前项目作为根目录,components 目录已经不在 demo1 目录范围内,所以是引用不到的

    小哥想到了 Webpack

    1. 整理目录

    • apps/:存放全部小程序
    • build/:存放构建脚本
    • common/:存放公共方法
    • components/:存放公共组件
    • styles/:存放公共样式
    • templates/:存放公共模板

    大概长这样

    图片描述

    2. 编写构建脚本

    package.json

    script: { "dev": "webpack --config build/webpack.config.js" } 

    build/webpack.config.js

    思路就是利用 CopyWebpackPlugin 同步指定的文件到小程序目录下

    const CopyWebpackPlugin = require('copy-webpack-plugin') const utils = require('./utils') // 获取 apps 目录下的小程序并指定公共文件目录命名 function copyToApps(dir) { let r = [] utils .exec(`cd ${utils.resolve('apps')} && ls`) .split('\n') .map(app => { r.push({ from: utils.resolve(dir), to: utils.resolve(`apps/${app}/_${dir}`) }) }) return r } module.exports = { watch: true, // 监听入口文件,保存便会刷新 entry: utils.resolve('index.js'), output: { path: utils.resolve('.tmp'), filename: 'bundle.js' }, plugins: [ // 同步指定的公共文件到所有小程序目录下 new CopyWebpackPlugin([ ...copyToApps('styles'), ...copyToApps('common'), ...copyToApps('templates'), ...copyToApps('components') ]) ] } 

    3. 启动本地开发

    npm run dev 

    图片描述

    图片描述

    现在公用的代码已经自动同步到小程序目录下,以下划线开头,当改动公共代码也会自动同步给小程序调用

    调用方式长这样

    import utils from './_common/utils' import com3 from './_components/com3' 
    @import './_styles/index.wxss'; 
    <import src="./_templates/index.wxml" /> 

    代码风格校验

    package.json

    script: { "lint": "eslint apps/" } 

    .eslintrc.js

    module.exports = { extends: 'standard', // 将小程序特有的全局变量排除下 globals: { Page: true, Component: true, App: true, getApp: true, wx: true }, rules: { 'space-before-function-paren': ['error', 'never'], 'no-unused-vars': [ 'error', { // 小程序还没支持 ES7,这个是用来兼容 async/await varsIgnorePattern: 'regeneratorRuntime' } ] } } 

    然后借助 husky 在每次 git commit 前执行校验

    script: { "precommit": "npm run lint" }, devDependencies: { "husky": "^0.14.3" } 

    清理

    最后小哥还加了个清理命令,便于重新生成公共代码

    package.json

    script: { "clean": "node build/clean.js" } 

    build/clean.js

    const rimraf = require('rimraf') const utils = require('./utils') function log(dir) { console.log(`cleaning ${dir}`) } rimraf(utils.resolve('.tmp'), () => log('.tmp')) utils .exec(`cd ${utils.resolve('apps')} && ls`) .split('\n') .map(app => { ;[ `${app}/_styles`, `${app}/_common`, `${app}/_templates`, `${app}/_components` ].map(m => { rimraf(utils.resolve(`apps/${m}`), () => log(m)) }) }) 

    码畜小哥心满意足

    “可以下班追剧了”

    码畜小哥简介

    考拉前端开发小哥 Bingo,钻研小程序开发。

    4 条回复    2019-04-18 15:00:44 +08:00
    airyland
        1
    airyland  
       2019-04-18 12:05:17 +08:00   1
    解决了问题,但是公用组件修改后还需要去确认调用的多个项目是否不兼容或者有 bug。还不如变成 pm 发布的形式来调用,可以有 changelog,需要更新的人有意识地测试是否有 bug。
    mscststs
        2
    mscststs  
       2019-04-18 13:57:03 +08:00
    我投一票 npm publish
    zbinlin
        3
    zbinlin  
       2019-04-18 14:07:45 +08:00
    nodejs 的项目,我都是通过 submodule + package.json 来管理公共的,但不方便(或没必要) publish 到 npm 的模块。
    meepo3927
        4
    meepo3927  
       2019-04-18 15:00:44 +08:00
    吊的一 b
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5480 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 07:36 PVG 15:36 LAX 23:36 JFK 02:36
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86