-
Notifications
You must be signed in to change notification settings - Fork 143
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement react-hot-loader transform (#376)
Fixes #228 Some details: * An eval snippet needed to be added to each class, which I decided to do unconditionally for simplicity. * A previous change already comptued the top-level declared variables, so I could just use those. * There was a bug where parameters in arrow function types were seen as top-level variables, so I changed it so types are never considered variable declarations. * In order to register the default export, we need to extract it to a variable, which required modifying both import transformers to handle that as a special case. * The ReactHotLoaderTransformer doesn't actually participate in normal transform, it just adds the snippets to the start and end. Cases not handled yet that could be handled in the future: * Avoid treating `require` statements as top-level declarations. * Skip react and react-hot-loader files themselves (Sucrase shouldn't be running on them anyway). I tested this end-to-end on a small app to make sure hot reloading works, including for bound methods.
- Loading branch information
1 parent
5f9f5e0
commit 72bc666
Showing
12 changed files
with
356 additions
and
7 deletions.
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
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,66 @@ | ||
import {IdentifierRole} from "../parser/tokenizer"; | ||
import TokenProcessor from "../TokenProcessor"; | ||
import Transformer from "./Transformer"; | ||
|
||
export default class ReactHotLoaderTransformer extends Transformer { | ||
private extractedDefaultExportName: string | null = null; | ||
|
||
constructor(readonly tokens: TokenProcessor, readonly filePath: string) { | ||
super(); | ||
} | ||
|
||
setExtractedDefaultExportName(extractedDefaultExportName: string): void { | ||
this.extractedDefaultExportName = extractedDefaultExportName; | ||
} | ||
|
||
getPrefixCode(): string { | ||
return ` | ||
(function () { | ||
var enterModule = require('react-hot-loader').enterModule; | ||
enterModule && enterModule(module); | ||
})();` | ||
.replace(/\s+/g, " ") | ||
.trim(); | ||
} | ||
|
||
getSuffixCode(): string { | ||
const topLevelNames = new Set(); | ||
for (const token of this.tokens.tokens) { | ||
if ( | ||
token.identifierRole === IdentifierRole.TopLevelDeclaration || | ||
token.identifierRole === IdentifierRole.ObjectShorthandTopLevelDeclaration | ||
) { | ||
topLevelNames.add(this.tokens.identifierNameForToken(token)); | ||
} | ||
} | ||
const namesToRegister = Array.from(topLevelNames).map((name) => ({ | ||
variableName: name, | ||
uniqueLocalName: name, | ||
})); | ||
if (this.extractedDefaultExportName) { | ||
namesToRegister.push({ | ||
variableName: this.extractedDefaultExportName, | ||
uniqueLocalName: "default", | ||
}); | ||
} | ||
return ` | ||
(function () { | ||
var reactHotLoader = require('react-hot-loader').default; | ||
var leaveModule = require('react-hot-loader').leaveModule; | ||
if (!reactHotLoader) { | ||
return; | ||
} | ||
${namesToRegister | ||
.map( | ||
({variableName, uniqueLocalName}) => | ||
` reactHotLoader.register(${variableName}, "${uniqueLocalName}", "${this.filePath}");`, | ||
) | ||
.join("\n")} | ||
leaveModule(module); | ||
})();`; | ||
} | ||
|
||
process(): boolean { | ||
return false; | ||
} | ||
} |
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
Oops, something went wrong.