-
Notifications
You must be signed in to change notification settings - Fork 11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(exoflex): add babel plugin for rewriting imports #341
Closed
Closed
Changes from all commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
f181b78
chore: ignore JS files from linting
darcien d830359
feat: add babel plugin for rewriting imports
darcien a736477
test: add test for the rewrite plugin
darcien fd876ef
feat: include babel plugin in package files
darcien 37860ce
chore: pin dependencies
darcien 8a097d1
docs: add plugin usage to readme
darcien 2532df7
fix: fix wrong path to mappings.json
darcien 9017d2e
chore: use babel plugin in example
darcien 2984c6e
chore: refactor webpack config alias
darcien e3847d7
chore: remove unused import from example
darcien 5c5f9f2
chore: fix stale yarn.lock
darcien 3d779d0
fix: fix default mappings.json path in plugin
darcien File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
jest.config.js | ||
*.js | ||
node_modules/ | ||
lib/ | ||
jestPresets/ | ||
coverage/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
module.exports = require('./lib/module/babel/index.js'); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
const path = require('path'); | ||
const fs = require('fs'); | ||
const types = require('@babel/types'); | ||
const parser = require('@babel/parser'); | ||
|
||
const packageJson = require('../package.json'); | ||
const root = path.resolve(__dirname, '..'); | ||
const output = path.join(root, 'lib/mappings.json'); | ||
const source = fs.readFileSync(path.resolve(root, 'src', 'index.ts'), 'utf8'); | ||
const ast = parser.parse(source, { | ||
sourceType: 'module', | ||
plugins: [ | ||
'jsx', | ||
'typescript', | ||
'objectRestSpread', | ||
'classProperties', | ||
'asyncGenerators', | ||
], | ||
}); | ||
|
||
const index = packageJson.module; | ||
const relative = (value) => | ||
path.relative(root, path.resolve(path.dirname(index), value)); | ||
|
||
const mappings = ast.program.body.reduce((acc, declaration, _, self) => { | ||
if (types.isExportNamedDeclaration(declaration)) { | ||
if (declaration.source) { | ||
declaration.specifiers.forEach((specifier) => { | ||
acc[specifier.exported.name] = { | ||
path: relative(declaration.source.value), | ||
name: specifier.local.name, | ||
}; | ||
}); | ||
} else { | ||
declaration.specifiers.forEach((specifier) => { | ||
const name = specifier.exported.name; | ||
|
||
self.forEach((it) => { | ||
if ( | ||
types.isImportDeclaration(it) && | ||
it.specifiers.some( | ||
(s) => | ||
types.isImportNamespaceSpecifier(s) && | ||
s.local.name === specifier.local.name, | ||
) | ||
) { | ||
acc[name] = { | ||
path: relative(it.source.value), | ||
name: '*', | ||
}; | ||
} | ||
}); | ||
}); | ||
} | ||
} | ||
|
||
return acc; | ||
}, {}); | ||
|
||
fs.existsSync(path.dirname(output)) || fs.mkdirSync(path.dirname(output)); | ||
fs.writeFileSync( | ||
output, | ||
JSON.stringify({ name: packageJson.name, index, mappings }, null, 2), | ||
); |
11 changes: 11 additions & 0 deletions
11
packages/exoflex/src/babel/__fixtures__/rewrite-imports/code.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import { Text } from 'react-native'; | ||
import { | ||
Provider as ExoflexProvider, | ||
Button, | ||
Label, | ||
NonExistent, | ||
NonExistentSecond as Stuff, | ||
DefaultTheme, | ||
Theme, | ||
RubikSourcesMap, | ||
} from 'exoflex'; |
8 changes: 8 additions & 0 deletions
8
packages/exoflex/src/babel/__fixtures__/rewrite-imports/output.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import { Text } from 'react-native'; | ||
import { Provider as ExoflexProvider } from "exoflex/lib/module/components"; | ||
import { Button } from "exoflex/lib/module/components"; | ||
import { Label } from "exoflex/lib/module/components/Typography"; | ||
import { NonExistent, NonExistentSecond as Stuff } from "exoflex/lib/module/index.js"; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is there a |
||
import { DefaultTheme } from "exoflex/lib/module/constants/themes"; | ||
import { Theme } from "exoflex/lib/module/types"; | ||
import { RubikSourcesMap } from "exoflex/lib/module/constants/fonts"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
const path = require('path'); | ||
const { spawnSync } = require('child_process'); | ||
const { create } = require('babel-test'); | ||
const { toMatchFile } = require('jest-file-snapshot'); | ||
|
||
expect.extend({ toMatchFile }); | ||
|
||
spawnSync('node', [ | ||
path.resolve(__dirname, '../../../scripts/generate-mappings.js'), | ||
]); | ||
|
||
const { fixtures } = create({ | ||
plugins: [ | ||
[ | ||
require.resolve('../index'), | ||
{ mappings: require.resolve('../../../lib/mappings.json') }, | ||
], | ||
], | ||
}); | ||
|
||
// Right now this test will ran once for each platform. | ||
// In the future, we should make it possible to run platform agnostic test files only once. | ||
fixtures('generate mappings', path.join(__dirname, '..', '__fixtures__')); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
const SKIP = Symbol('SKIP'); | ||
|
||
module.exports = function rewire(babel, options) { | ||
const t = babel.types; | ||
|
||
const { name, index, mappings } = require(options.mappings || | ||
'../../mappings.json'); | ||
|
||
return { | ||
visitor: { | ||
ImportDeclaration(path) { | ||
if (path.node.source.value !== name || path.node[SKIP]) { | ||
return; | ||
} | ||
|
||
path.node.source.value = `${name}/${index}`; | ||
path.replaceWithMultiple( | ||
path.node.specifiers.reduce((declarations, specifier) => { | ||
const mapping = mappings[specifier.imported.name]; | ||
|
||
if (mapping) { | ||
const alias = `${name}/${mapping.path}`; | ||
const identifier = t.identifier(specifier.local.name); | ||
|
||
let s; | ||
|
||
switch (mapping.name) { | ||
case 'default': | ||
s = t.importDefaultSpecifier(identifier); | ||
break; | ||
case '*': | ||
s = t.importNamespaceSpecifier(identifier); | ||
break; | ||
default: | ||
s = t.importSpecifier(identifier, t.identifier(mapping.name)); | ||
} | ||
|
||
declarations.push( | ||
t.importDeclaration([s], t.stringLiteral(alias)), | ||
); | ||
} else { | ||
const previous = declarations.find( | ||
(d) => d.source.value === path.node.source.value, | ||
); | ||
|
||
if (previous) { | ||
previous.specifiers.push(specifier); | ||
} else { | ||
const node = t.importDeclaration([specifier], path.node.source); | ||
node[SKIP] = true; | ||
declarations.push(node); | ||
} | ||
} | ||
|
||
return declarations; | ||
}, []), | ||
); | ||
|
||
path.requeue(); | ||
}, | ||
}, | ||
}; | ||
}; |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is exactly what I need for the vision-ui source transformer! (although I need to use the typescript parser)