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

推荐订阅源

F
Fortinet All Blogs
MyScale Blog
MyScale Blog
Microsoft Security Blog
Microsoft Security Blog
量子位
B
Blog
aimingoo的专栏
aimingoo的专栏
Apple Machine Learning Research
Apple Machine Learning Research
阮一峰的网络日志
阮一峰的网络日志
The GitHub Blog
The GitHub Blog
T
The Exploit Database - CXSecurity.com
N
News | PayPal Newsroom
Cloudbric
Cloudbric
A
About on SuperTechFans
AI
AI
Hacker News: Ask HN
Hacker News: Ask HN
S
Schneier on Security
Recent Commits to openclaw:main
Recent Commits to openclaw:main
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
C
Cyber Attacks, Cyber Crime and Cyber Security
L
LINUX DO - 最新话题
T
The Blog of Author Tim Ferriss
Simon Willison's Weblog
Simon Willison's Weblog
有赞技术团队
有赞技术团队
H
Heimdal Security Blog
J
Java Code Geeks
大猫的无限游戏
大猫的无限游戏
D
Docker
Security Archives - TechRepublic
Security Archives - TechRepublic
N
News and Events Feed by Topic
IT之家
IT之家
Know Your Adversary
Know Your Adversary
N
Netflix TechBlog - Medium
T
Tailwind CSS Blog
B
Blog RSS Feed
C
Cybersecurity and Infrastructure Security Agency CISA
C
Cisco Blogs
博客园 - 叶小钗
美团技术团队
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
H
Hackread – Cybersecurity News, Data Breaches, AI and More
L
LangChain Blog
The Hacker News
The Hacker News
Y
Y Combinator Blog
I
Intezer
The Register - Security
The Register - Security
F
Full Disclosure
V
V2EX
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Last Week in AI
Last Week in AI
Martin Fowler
Martin Fowler

博客园 - 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。