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 · 2999 次点击
    这是一个创建于 2065 天前的主题,其中的信息可能已经有所发展或是发生改变。

    故事是这样开始的

    前端开发小哥 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。还不如变成 npm 发布的形式来调用,可以有 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   ·   实用小工具   ·   5085 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 03:35 · PVG 11:35 · LAX 19:35 · JFK 22:35
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.