惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

S
SegmentFault 最新的问题
B
Blog
P
Proofpoint News Feed
美团技术团队
The GitHub Blog
The GitHub Blog
Y
Y Combinator Blog
A
About on SuperTechFans
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Vercel News
Vercel News
有赞技术团队
有赞技术团队
小众软件
小众软件
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Google DeepMind News
Google DeepMind News
Martin Fowler
Martin Fowler
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
aimingoo的专栏
aimingoo的专栏
H
Help Net Security
罗磊的独立博客
L
LangChain Blog
GbyAI
GbyAI
腾讯CDC
T
The Blog of Author Tim Ferriss
Microsoft Security Blog
Microsoft Security Blog

博客园 - Liaofy

前端新范式:用 AI 提效开发,用 E2E 保证迭代质量 把SPA的加载速度提升一倍,有没有搞头? 使用mumu模拟器抓包 andriod app 如何在本地给 vue-router4 扩展功能? Vue3 路由优化,使页面初次渲染效率翻倍 【eslint 插件开发】禁用 location 跳转外部链接 vue 项目使用 charles 代理线上页面到本地后显示404 避免使用单个数字作为对象的key 高扩展弹出层组件设计实现(H5&小程序) 轻松搞懂POST与PUT的区别 vite(or rollup) 实现 webpackChunkName webapp项目架构畅想(vue3).md vite试玩:老项目启动从6分钟到秒开 【uniapp】改善中大型uniapp小程序项目开发体验 vscode 调试 webpack 打包 5分钟,搞清 Unicode 与 UTF-8 的区别 deAsync.js 真正让异步变同步 盘的转——使用缓动函数完成动画 多个请求间断失败,如何优雅处理?
修剪AST树减少webapck打包尺寸
Liaofy · 2021-12-01 · via 博客园 - Liaofy

背景

公司每年都有不同的H5活动(vue2)上线、下线,这些代码都在存在于同一个仓库中。

虽然过期的活动代码,增加了无效的编译时间和打包内容,但是我们并不想删除它们,毕竟代码即资产。

所以,我们希望实现一种方案,既能保留所有活动路由,又能将过期活动内容从包中剔除。

webpack loader

loader 用于对模块的源代码进行转换。我们可以编写一个 loader 来参与 webpack 打包过程,进而修改源代码。一个最简单的 loader 如下——它把接收到的源码原封不动的返回了:

module.exports = function doNothingLoader(content) {
  return content
}

修剪路由AST

使用自定义 loader,我们就可以在 webpack 打包时修改源码而不会产生副作用。具体的思路是:通过this.resourcePath识别源代码是否为路由文件,若是,则解析代码,并将其中的component字段删除,以达到保留路由而删除内容的目的。

router.js源码

import router from "@/router";
const routes = [{
  name: 'test',
  path: '/promotion/test',
  component: () => import(/* webpackChunkName: 'promotion/pages/test' */'./pages/test/index'),
  meta: {
    title: '测试'
  }
}]
router.addRoutes(routes);

修剪后(删除了 component 字段)

import router from "@/router";
const routes = [{
  name: 'test',
  path: '/promotion/test',

  meta: {
    title: '测试'
  }
}]
router.addRoutes(routes);

代码实现

通过 babel 插件,可以修改 babel 转换后的 AST 树。复制任何有效的JS代码到astexplorer,能够非常清晰的看到其AST结构。

我们要做的事就变得很简单了:如果是路由文件,则遍历其 AST,找到component字段并删除。

const babel = require('babel-core'); // v6.26.0
const isWin = /^win/.test(process.platform)
const normalizePath = path => (isWin ? path.replace(/\\/g, '/') : path)
const routerRegx = /projects\/test\/(.*)router\.js/
const isInvalidRoute = () => null // 根据项目实际情况实现 isInvalidRoute

const pruneInvalidRoute = {
  visitor: {
    ObjectExpression(path) {
      const pathNode = (path.node.properties || []).find(p => p.key.name === 'path') 
      if (pathNode) {
        const routeVal = pathNode.value.value || ''
        if (isInvalidRoute(routeVal) {
          const compIndex = properties.findIndex(p => p.key.name === 'component')
          if (compIndex >= 0) {
            properties.splice(compIndex, 1)
            return
          }
        }
      }
    }
  }
}

module.exports = function pruneInvalidRouteLoader(content) {
  const filePath = normalizePath(this.resourcePath)
  const matched = routerRegx.test(filePath)
  if (!matched) return content
  const result = babel.transformFileSync(filePath, {plugins: [pruneInvalidRoute]})
  return result.code
}

唯一要注意的是,由于 babel 的版本差异,其接口略有不同,具体可查看版本对应文档。本文所用的babel-core版本为:6.26.0。