Skip to content

Commit 2605da6

Browse files
authored
feat: add support for import.meta.hot (#15)
1 parent 081c514 commit 2605da6

File tree

16 files changed

+362
-8
lines changed

16 files changed

+362
-8
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ This repo includes the following presets and plugins:
2424
- [babel-preset-vite](./packages/babel-preset-vite)
2525
- [babel-plugin-transform-vite-meta-env](./packages/babel-plugin-transform-vite-meta-env)
2626
- [babel-plugin-transform-vite-meta-glob](./packages/babel-plugin-transform-vite-meta-glob)
27+
- [babel-plugin-transform-vite-meta-hot](./packages/babel-plugin-transform-vite-meta-hot)
2728

2829
For installation, usage and example, please refer to the documentation in the above packages.
2930

@@ -41,6 +42,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
4142
<td align="center"><a href="https://github.com/MohitPopli"><img src="https://avatars.githubusercontent.com/u/17976072?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Mohit</b></sub></a><br /><a href="https://github.com/OpenSourceRaidGuild/babel-vite/commits?author=MohitPopli" title="Code">💻</a></td>
4243
<td align="center"><a href="https://rubenmoya.dev/"><img src="https://avatars.githubusercontent.com/u/905225?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Rubén Moya</b></sub></a><br /><a href="https://github.com/OpenSourceRaidGuild/babel-vite/commits?author=rubenmoya" title="Code">💻</a></td>
4344
<td align="center"><a href="https://github.com/mitchelvanbever"><img src="https://avatars.githubusercontent.com/u/10127707?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Mitchel van Bever</b></sub></a><br /><a href="#ideas-mitchelvanbever" title="Ideas, Planning, & Feedback">🤔</a></td>
45+
<td align="center"><a href="https://kelvinzhang.com/"><img src="https://avatars.githubusercontent.com/u/9621004?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Kelvin Zhang</b></sub></a><br /><a href="https://github.com/OpenSourceRaidGuild/babel-vite/commits?author=0kzh" title="Code">💻</a><a href="https://github.com/OpenSourceRaidGuild/babel-vite/commits?author=0kzh" title="Tests">⚠️</a> <a href="https://github.com/OpenSourceRaidGuild/babel-vite/commits?author=0kzh" title="Documentation">📖</a></td>
4446
</tr>
4547
</table>
4648

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,12 @@
4848
"build": "run-p --aggregate-output build:**",
4949
"build:babel-plugin-transform-vite-meta-env": "npm run build --prefix packages/babel-plugin-transform-vite-meta-env",
5050
"build:babel-plugin-transform-vite-meta-glob": "npm run build --prefix packages/babel-plugin-transform-vite-meta-glob",
51+
"build:babel-plugin-transform-vite-meta-hot": "npm run build --prefix packages/babel-plugin-transform-vite-meta-hot",
5152
"build:babel-preset-vite": "npm run build --prefix packages/babel-preset-vite",
5253
"test": "run-p --aggregate-output test:** --",
5354
"test:babel-plugin-transform-vite-meta-env": "npm run test --prefix packages/babel-plugin-transform-vite-meta-env -- --coverage",
5455
"test:babel-plugin-transform-vite-meta-glob": "npm run test --prefix packages/babel-plugin-transform-vite-meta-glob -- --coverage",
56+
"test:babel-plugin-transform-vite-meta-hot": "npm run test --prefix packages/babel-plugin-transform-vite-meta-hot -- --coverage",
5557
"test:babel-preset-vite": "npm run test --prefix packages/babel-preset-vite -- --coverage",
5658
"typecheck": "kcd-scripts typecheck",
5759
"lint": "kcd-scripts lint",
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
package-lock=false
2+
legacy-peer-deps=true
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
MIT License
2+
3+
Copyright (c) [2021] [Michael Peyper]
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
6+
associated documentation files (the "Software"), to deal in the Software without restriction,
7+
including without limitation the rights to use, copy, modify, merge, publish, distribute,
8+
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
9+
furnished to do so, subject to the following conditions:
10+
11+
The above copyright notice and this permission notice shall be included in all copies or substantial
12+
portions of the Software.
13+
14+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
15+
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
17+
OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# babel-plugin-transform-vite-meta-hot
2+
3+
<!-- prettier-ignore-start -->
4+
[![Build Status](https://img.shields.io/github/workflow/status/OpenSourceRaidGuild/babel-vite/validate?logo=github&style=flat-square)](https://github.com/OpenSourceRaidGuild/babel-vite/actions?query=workflow%3Avalidate)
5+
[![codecov](https://img.shields.io/codecov/c/github/OpenSourceRaidGuild/babel-vite.svg?style=flat-square)](https://codecov.io/gh/OpenSourceRaidGuild/babel-vite)
6+
[![version](https://img.shields.io/npm/v/babel-plugin-transform-vite-meta-hot.svg?style=flat-square)](https://www.npmjs.com/package/babel-plugin-transform-vite-meta-hot)
7+
[![downloads](https://img.shields.io/npm/dm/babel-plugin-transform-vite-meta-hot.svg?style=flat-square)](http://www.npmtrends.com/babel-plugin-transform-vite-meta-hot)
8+
[![MIT License](https://img.shields.io/npm/l/babel-plugin-transform-vite-meta-hot.svg?style=flat-square)](https://github.com/OpenSourceRaidGuild/babel-vite/blob/master/LICENSE.md)
9+
10+
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com)
11+
[![Code of Conduct](https://img.shields.io/badge/code%20of-conduct-ff69b4.svg?style=flat-square)](https://github.com/OpenSourceRaidGuild/babel-vite/blob/master/CODE_OF_CONDUCT.md)
12+
[![Discord](https://img.shields.io/discord/808364903822917662.svg?color=7389D8&labelColor=6A7EC2&logo=discord&logoColor=ffffff&style=flat-square)](https://discord.gg/grS89HWeYh)
13+
14+
[![Watch on GitHub](https://img.shields.io/github/watchers/OpenSourceRaidGuild/babel-vite.svg?style=social)](https://github.com/OpenSourceRaidGuild/babel-vite/watchers)
15+
[![Star on GitHub](https://img.shields.io/github/stars/OpenSourceRaidGuild/babel-vite.svg?style=social)](https://github.com/OpenSourceRaidGuild/babel-vite/stargazers)
16+
[![Tweet](https://img.shields.io/twitter/url/https/github.com/OpenSourceRaidGuild/babel-vite.svg?style=social)](https://twitter.com/intent/tweet?text=Check%20out%20babel-plugin-transform-vite-meta-hot%20by%20OpenSourceRaidGuild%20https%3A%2F%2Fgithub.com%2FOpenSourceRaidGuild%2Fbabel-vite%20%F0%9F%91%8D)
17+
<!-- prettier-ignore-end -->
18+
19+
> Please note: this plugin is intended to provide an approximation of some of Vite specific
20+
> transformations when running the code in non-Vite environment, for example, running tests with a
21+
> NodeJS based test runner.
22+
>
23+
> **The functionality within these transformations should not be relied upon in production.**
24+
25+
## Example
26+
27+
**In**
28+
29+
```
30+
if (import.meta.hot) {
31+
import.meta.hot.accept(callback);
32+
}
33+
```
34+
35+
**Out**
36+
37+
```
38+
if (module.hot) {
39+
module.hot.accept(callback);
40+
}
41+
```
42+
43+
## Installation
44+
45+
```sh
46+
npm install --save-dev babel-plugin-transform-vite-meta-hot
47+
```
48+
49+
## Usage
50+
51+
### With a configuration file (Recommended)
52+
53+
```json
54+
{
55+
"plugins": ["babel-plugin-transform-vite-meta-hot"]
56+
}
57+
```
58+
59+
### Via CLI
60+
61+
```sh
62+
babel --plugins babel-plugin-transform-vite-meta-hot script.js
63+
```
64+
65+
### Via Node API
66+
67+
```javascript
68+
require('@babel/core').transformSync('code', {
69+
plugins: ['babel-plugin-transform-vite-meta-hot']
70+
})
71+
```
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
{
2+
"name": "babel-plugin-transform-vite-meta-hot",
3+
"version": "0.0.0-semantically-released",
4+
"description": "babel plugin that emulates vite's import.meta.hot functionality",
5+
"main": "lib/index.js",
6+
"typings": "lib/index.d.ts",
7+
"files": [
8+
"lib",
9+
"src"
10+
],
11+
"repository": {
12+
"type": "git",
13+
"url": "git+https://github.com/OpenSourceRaidGuild/babel-vite.git"
14+
},
15+
"keywords": [
16+
"babel",
17+
"vite",
18+
"plugin",
19+
"import",
20+
"meta",
21+
"hot"
22+
],
23+
"author": "Kelvin Zhang <[email protected]>",
24+
"license": "MIT",
25+
"bugs": {
26+
"url": "https://github.com/OpenSourceRaidGuild/babel-vite/issues"
27+
},
28+
"homepage": "https://github.com/OpenSourceRaidGuild/babel-vite#readme",
29+
"scripts": {
30+
"build": "kcd-scripts build --out-dir lib",
31+
"test": "kcd-scripts test"
32+
},
33+
"devDependencies": {
34+
"@babel/core": "^7.13.8",
35+
"@types/babel-plugin-tester": "^9.0.1",
36+
"babel-plugin-tester": "^10.0.0",
37+
"kcd-scripts": "^12.0.0",
38+
"typescript": "^4.2.2"
39+
},
40+
"dependencies": {
41+
"@babel/runtime": "^7.13.9",
42+
"@types/babel__core": "^7.1.12"
43+
}
44+
}
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`vite-meta-hot not import.meta lookup: not import.meta lookup 1`] = `
4+
5+
const x = import.meta()
6+
7+
↓ ↓ ↓ ↓ ↓ ↓
8+
9+
const x = import.meta()
10+
11+
12+
`;
13+
14+
exports[`vite-meta-hot not replace import.meta.hot: not replace import.meta.hot 1`] = `
15+
16+
const x = module.hot
17+
18+
↓ ↓ ↓ ↓ ↓ ↓
19+
20+
const x = module.hot
21+
22+
23+
`;
24+
25+
exports[`vite-meta-hot not replace key access: not replace key access 1`] = `
26+
27+
const key = "env"; const x = import.meta[key]
28+
29+
↓ ↓ ↓ ↓ ↓ ↓
30+
31+
const key = 'env'
32+
const x = import.meta[key]
33+
34+
35+
`;
36+
37+
exports[`vite-meta-hot not replace string access: not replace string access 1`] = `
38+
39+
const x = import.meta["env"]
40+
41+
↓ ↓ ↓ ↓ ↓ ↓
42+
43+
const x = import.meta['env']
44+
45+
46+
`;
47+
48+
exports[`vite-meta-hot not replaceable: not replaceable 1`] = `
49+
50+
const x = import.meta.other
51+
52+
↓ ↓ ↓ ↓ ↓ ↓
53+
54+
const x = import.meta.other
55+
56+
57+
`;
58+
59+
exports[`vite-meta-hot replace import.meta.hot: replace import.meta.hot 1`] = `
60+
61+
const x = import.meta.hot
62+
63+
↓ ↓ ↓ ↓ ↓ ↓
64+
65+
const x = module.hot
66+
67+
68+
`;
69+
70+
exports[`vite-meta-hot replace key access: replace key access 1`] = `
71+
72+
const key = "hot"; const x = import.meta[key]
73+
74+
↓ ↓ ↓ ↓ ↓ ↓
75+
76+
const key = 'hot'
77+
const x = module.hot
78+
79+
80+
`;
81+
82+
exports[`vite-meta-hot replace string access: replace string access 1`] = `
83+
84+
const x = import.meta["hot"]
85+
86+
↓ ↓ ↓ ↓ ↓ ↓
87+
88+
const x = module.hot
89+
90+
91+
`;
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import pluginTester from 'babel-plugin-tester'
2+
import plugin from '..'
3+
4+
pluginTester({
5+
plugin,
6+
pluginName: 'vite-meta-hot',
7+
snapshot: true,
8+
tests: {
9+
'replace import.meta.hot': 'const x = import.meta.hot',
10+
'not replace import.meta.hot': 'const x = module.hot',
11+
'replace string access': 'const x = import.meta["hot"]',
12+
'not replace string access': 'const x = import.meta["env"]',
13+
'replace key access': 'const key = "hot"; const x = import.meta[key]',
14+
'not replace key access': 'const key = "env"; const x = import.meta[key]',
15+
'not replaceable': 'const x = import.meta.other',
16+
'not import.meta lookup': 'const x = import.meta()'
17+
}
18+
})
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import type babelCore from '@babel/core'
2+
3+
export default function viteMetaHotBabelPlugin({
4+
template,
5+
types: t
6+
}: typeof babelCore): babelCore.PluginObj {
7+
return {
8+
name: 'vite-meta-hot',
9+
visitor: {
10+
MemberExpression(path) {
11+
const isMetaProperty = t.isMetaProperty(path.node.object)
12+
const isHotVar = t.isIdentifier(path.node.property) && path.node.property.name === 'hot'
13+
14+
if (!isMetaProperty || !isHotVar) {
15+
return
16+
}
17+
18+
path.replaceWith(template.expression.ast('module.hot'))
19+
},
20+
StringLiteral(path) {
21+
const isMetaProperty =
22+
t.isMemberExpression(path.parentPath.node) &&
23+
t.isMetaProperty(path.parentPath.node.object)
24+
const isHotVar = path.node.value === 'hot'
25+
26+
if (!isMetaProperty || !isHotVar) {
27+
return
28+
}
29+
30+
path.parentPath.replaceWith(template.expression.ast('module.hot'))
31+
},
32+
Identifier(path) {
33+
if (
34+
!t.isMemberExpression(path.parentPath.node) ||
35+
!t.isMetaProperty(path.parentPath.node.object)
36+
) {
37+
return
38+
}
39+
40+
const key = path.node.name
41+
/* @ts-expect-error outdated types */
42+
// eslint-disable-next-line
43+
const keyValue = path.scope.getBinding(key)?.path.node.init?.value
44+
if (keyValue !== 'hot') {
45+
return
46+
}
47+
48+
path.parentPath.replaceWith(template.expression.ast('module.hot'))
49+
}
50+
}
51+
}
52+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"extends": "../../tsconfig.json",
3+
"include": ["src/**/*"]
4+
}

0 commit comments

Comments
 (0)