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

推荐订阅源

Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Recent Announcements
Recent Announcements
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
A
About on SuperTechFans
I
InfoQ
F
Full Disclosure
美团技术团队
Martin Fowler
Martin Fowler
量子位
V
V2EX
小众软件
小众软件
爱范儿
爱范儿
宝玉的分享
宝玉的分享
aimingoo的专栏
aimingoo的专栏
有赞技术团队
有赞技术团队
F
Fortinet All Blogs
M
MIT News - Artificial intelligence
T
Tailwind CSS Blog
博客园 - 三生石上(FineUI控件)
N
Netflix TechBlog - Medium
大猫的无限游戏
大猫的无限游戏
Vercel News
Vercel News
IT之家
IT之家
云风的 BLOG
云风的 BLOG
B
Blog RSS Feed
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Hugging Face - Blog
Hugging Face - Blog
Microsoft Azure Blog
Microsoft Azure Blog
T
Threat Research - Cisco Blogs
T
Threatpost
P
Proofpoint News Feed
腾讯CDC
博客园 - 司徒正美
Jina AI
Jina AI
The Hacker News
The Hacker News
P
Privacy & Cybersecurity Law Blog
L
LINUX DO - 热门话题
S
Securelist
U
Unit 42
T
The Exploit Database - CXSecurity.com
博客园 - Franky
NISL@THU
NISL@THU
D
Docker
The GitHub Blog
The GitHub Blog
Latest news
Latest news
S
Schneier on Security
J
Java Code Geeks
Blog — PlanetScale
Blog — PlanetScale
P
Palo Alto Networks Blog

任峻宏的小站

Debugging Memory Leaks in a Next.js Application Troubleshooting: Resolving Devise Issue in an API-only Application How to Customize a Right-Click Menu in React Using ActionCable and React to Create a Simple Chat App 纪念左耳朵耗子 - 任峻宏的小站 Using SSE to Implement ChatGPT in Rails Refresh Myself - 任峻宏的小站 战痘 - 任峻宏的小站 逆向的能量——生活需要批评者 - 任峻宏的小站 人活着必须要有目标 - 任峻宏的小站 《第一人称单数》读书笔记 - 任峻宏的小站 卸载英雄联盟 - 任峻宏的小站 我的 2021 年总结 - 任峻宏的小站 记我的爷爷 - 任峻宏的小站 《人生算法》读书笔记 - 任峻宏的小站 《不拘一格》读书笔记 - 任峻宏的小站 我为什么很少写博客 - 任峻宏的小站 我的2020年总结 - 任峻宏的小站 如何避免冲动消费? - 任峻宏的小站 《不能不去爱的两件事》读书笔记 - 任峻宏的小站 记一次搬家 - 任峻宏的小站 My blog V3.0 has been published! 解决服务器上运行 bundle install 时 killed 的问题 解决生产环境不能发送邮件的问题 - 任峻宏的小站 解决内存泄漏记录 - 任峻宏的小站 勿忘初心 - 任峻宏的小站 关于 RSpec 的一点方法总结 - 任峻宏的小站 使用 AJAX 重载部分页面 - 任峻宏的小站 Nginx 添加 SSL 支持 - 任峻宏的小站 Nginx 中进行重定向配置 - 任峻宏的小站 记我的第二次部署 - 任峻宏的小站 写在“毕业”之际 - 任峻宏的小站 JS 简单实现弹出层效果 - 任峻宏的小站 速递易工作总结及感想 - 任峻宏的小站 在 Aliyun ECS 上用 Nginx + Passenger 部署 Rails 应用时安装 Passenger 的问题 [译] Common Rails Idioms that Kill Database Performance Git 常用操作总结 - 任峻宏的小站 [译] Terminal 功夫——方便开发者的实用技巧 - 任峻宏的小站 实例方法与类方法 - 任峻宏的小站 各种报错解决集合 - 任峻宏的小站
Migrate from Webpacker to Vite 从入门到放弃
任峻宏 · 2021-07-17 · via 任峻宏的小站

前言

听闻 Vite 速度很快,最近开始考虑把项目里面的 webpack 打包换成 Vite

虽然折腾了一波之后最后放弃了,还是记录一下过程,算是一篇踩坑记录


由于是 Rails 项目,我就直接使用封装好的 vite_ruby 开始搞了

看了下官方文档,感觉很清晰,再根据 这个步骤,常规操作搞一波,该 install 的 install 完,再替换下 javascript_packs_tag 什么的,试了一下启动,果然飞快,感觉要大功告成了:

- 再一看发现样式都没有出来,css 文件没有加载,得用  <%= vite_stylesheet_tag 'application.scss' %> 加载一下,另外如果是 scss 格式的话必须显示指定一下

- 接下来会发现大量这样的错误:

原因很简单,我们项目里用了 React 自然有大量的 JSX 语法,但是我们很多文件后缀是 .js 命名的,而在 JS 文件里的 JSX 语法是被 Vite 认为不支持的

Vite assumes that js files contain only js valid syntax. But jsx has another AST and therefore is only supported in jsx files

尤大大也说了 (https://twitter.com/youyuxi/status/1362050255009816577),本来 JS 文件大多数情况下是不需要完全的 AST transform 的,如果要支持 JS 文件里的 JSX 语法的话,相当于所有文件都需要被 full-AST-processed.  这样其实不是一个好的做法

那怎么解决呢?找了三个方案:
1. 替换所有 .js 文件为 .jsx 或者 .tsx
2. 使用 plugin (https://github.com/dravenww/vite-plugin-react-js-support) 增加对 JS 文件中的语法支持
3. 使用 esbuilder 配置 loader 来解析文件,原理和方案2一样

最后我选了方案1,虽然要替换几百个文件看起来改动很大,但这个应该才是正确的做法,本来就不该命名为 .js

跑了个 shell 批量给替换了:find app/javascript/components -name "*.js" -exec sh -c 'mv "$0" "${0%.js}.tsx"' {} \;

- JSX 的问题搞定了,发现出现了另一个问题,大量的文件在 import 的时候找不到,之前用相对路径写的全都不能用了

例如 import XX from 'components/form/xxxx' 都得替换成 import XX from '~/components/form/xxxx'

这个好解决,在  vite.config.ts 里配置一下 resolve path 就好了:

import { defineConfig } from 'vite'
import { resolve } from 'path'
import RubyPlugin, { projectRoot } from 'vite-plugin-ruby'

export default defineConfig({
  plugins: [
    RubyPlugin()
  ],
  resolve: {
    alias: [
      { find: 'components', replacement: resolve(__dirname, 'app/javascript/components') },
      { find: 'shared', replacement: resolve(__dirname, 'app/javascript/shared') },
      { find: 'actions', replacement: resolve(__dirname, 'app/javascript/actions') },
      { find: 'stores', replacement: resolve(__dirname, 'app/javascript/stores') }
    ]
  }
})

- 下一个问题,Webpack 里的 require.context 在 Vite 里是不能用的,需要用 glob-import 来做

比如 const componentRequireContext = require.context('components', true) 需要改成 const componentRequireContext = import.meta.globEager('../components/**')

另外其他用到 require 的地方也得改成 import

否则就会出现 require is not defined 的报错

因为 Vite 是完全依靠 ESM 原生能力的,也就是说它只认 import, 而 require 是 CJS 里的方法。我们的代码最终被送到浏览器里执行,浏览器本身就没定义这个方法,所以就报错了。

这里和 Webpack 不一样,Webpack 事先会编译打包好,到浏览器的时候已经把 require 转成浏览器能识别的方式了。

所以这里还是有点难受的,好在我这项目里 require 的地方不多,勉强把这个坑踩过去了。


- 最后终于把所有报错解决了,也跑起来了,发现有点不对,页面显示基本都不完整,很多东西都没显示出来。

这里要说的是,我们项目里很多地方不是 React 全局接管路由的,也就是说不是纯前端渲染,而是用了 react_rails 的方式来渲染的前端组件,问题就出在这儿,这种方式渲染的内容都没有显示出来。

猜测是这种方式引用的前端组件没有被 Vite 识别到。

于是翻到了社区的讨论:

vite_ruby 这边作者表示自己没有用过 react_rails, 可能不太兼容, 建议 react_rails 作者去支持组件注册 https://github.com/ElMassimo/vite_ruby/discussions/86

而看到 react_rails 这边对于 Vite 的支持也没有明确进展 https://github.com/reactjs/react-rails/issues/1134

玩到这里,我就基本放弃了,溜了溜了。

结语

如果是对于新项目,确实可以尝试 Vite,速度会有提升;如果对于依赖太多的老项目,迁移起来可能会比较麻烦。