new styles extractor#353
Conversation
|
So awesome! I didn't have time to look at the code yet but will be looking when I have time. Don't worry about my TypeScript branch for now. I don't think I'll have time to complete it this month. But if you want to use TypeScript, maybe you can use it for the new code you write. Then when we migrate, we will only need to migrate the old code. |
|
It would be better if you didn't look at the code now :) |
|
I guess it's ready for review. |
|
Hey, @Anber thank you for your PR. We really appreciate your contribution and we would like to have it merged, but at the time being I'm having a hard time understanding the code without types, so here's what we are going to do: I'll finish up the migration to TS and then I'll ask you to migrate your code. Sorry for requesting more work from your side. I hope you'll understand our decision. |
|
Hi! It’s ok. Can I take @satya164’s branch as a base for migration? |
|
I've finished with |
|
@zamotany I have some free time, can I help you with migration? |
|
@Anber I'm in the process of setting up the infra for the migration (build pipeline, ESLint, etc), once it's done, you can jump in and help me migrate files. I was thinking about migrating the source code only first (excluding test, fixtures, website etc), since it can be done later. |
|
@zamotany Ok. Let's me know when you will be ready! |
|
@Anber I have setup the infra for the migration here: https://github.com/callstack/linaria/tree/feature/typescript-migration so you can do PRs agains this branch |
|
I've changed the PR base. There are still two failed tests with dependencies that I mentioned before but everything else seems to be ok. |
|
@satya164 could you please check tests
|
|
I've migrated |
|
➜ linaria ✗ yarn tsc --noEmit |
|
New branch for the next big release sounds good. We can collect all potential BC features in it and publish something like canary. |
|
+1 for migrating under a dedicated branch |
|
@Anber I have created a dedicated branch |
|
I'll try to separate extractor and migration to two different PR but it wouldn't be simple, so I need some time. |
|
@Anber just extract the files that are common to Also, how about moving the files related to dep grath etc to a separate directory? Instead them living in |
|
Hi @zamotany!
It's a good idea! |
|
@Anber that's fine too. Also I think you can update those 2 failing snapshots. |
|
@Anber can you resolve the conflicts? |
|
@zamotany, I hope, now it's ready for review :) |
zamotany
left a comment
There was a problem hiding this comment.
Maybe we should call dumpNode if some environment variable is set? Like LINARIA_DEBUG?
| return ( | ||
| this.edges | ||
| // shallowEqual is not defined | ||
| .filter(([a]) => (t as any).shallowEqual(a, like)) |
There was a problem hiding this comment.
Can you explain what this comment is about and why are we casting t to any??
There was a problem hiding this comment.
Oops, I've missed the second part of the comment in babel typings. Anyway, I'll add this shallowEqual to DefinitelyTyped and remove this any when the new version of @types/babel__core is published.
| return this.bindingsDependents.get(id) || []; | ||
| } | ||
|
|
||
| findDependencies(like: object) { |
There was a problem hiding this comment.
| findDependencies(like: object) { | |
| findDependencies(like: Object) { |
| ); | ||
| } | ||
|
|
||
| findDependents(like: object) { |
There was a problem hiding this comment.
| findDependents(like: object) { | |
| findDependents(like: Object) { |
| } | ||
| } | ||
|
|
||
| class GraphBuilder { |
There was a problem hiding this comment.
Can we split those 2 classes into separate files?
| } | ||
| } | ||
|
|
||
| private readonly graph: Graph; |
There was a problem hiding this comment.
| private readonly graph: Graph; | |
| private readonly scope: ScopeManager = new ScopeManager(); |
|
|
||
| const { type } = node; | ||
| // VISITOR_KEYS is not defined in babel typings | ||
| const keys: [keyof T] = (t as any).VISITOR_KEYS[type] || []; |
There was a problem hiding this comment.
Maybe let's keep VISITOR_KEYS in some file, types.ts maybe, since it's used in multiple files.
| } | ||
| } | ||
|
|
||
| return Object.keys(changes).length ? Object.assign({}, node, changes) : node; |
There was a problem hiding this comment.
| return Object.keys(changes).length ? Object.assign({}, node, changes) : node; | |
| return Object.keys(changes).length | |
| ? { ...node, ...changes } | |
| : node; |
| * Adds to the end of module export of array of evaluated values or evaluation errors. | ||
| * Returns new AST and an array of external dependencies. | ||
| */ | ||
| function shake( |
There was a problem hiding this comment.
| function shake( | |
| export default function shake( |
| ]; | ||
| } | ||
|
|
||
| export default shake; |
There was a problem hiding this comment.
| export default shake; |
| } | ||
|
|
||
| const shaken = shakeNode(rootPath, alive) as t.Program; | ||
| // dumpNode(program, alive); |
There was a problem hiding this comment.
| // dumpNode(program, alive); |
|
@zamotany, done. I've split |
|
it's failing on this const declared = this.meta.get('declared') as t.Identifier[];
declared.forEach(n =>
this.graph.externalDeps.push({
source,
local: n,
imported: null,
})
); |
|
It had expected some variable declaration, but received bare |
|
Huge thanks @Anber 👍 |
|
Thank you! |
It was an error :) I'll fix it soon. |

Summary
This is a PoC of more advanced styles extractor. It can evaluate almost any js code whereas current extractor has problems with code like this:
Unlike current implementation, this extractor does not evaluate expressions immediately in
TaggedTemplateExpressionvisitor but collects them for later evaluation. Then it builds a dependency graph for all expressions and strips all unrelated code from a module. On the last stage, it does a batch evaluation of all expressions.I've created this PR in WIP stage because I had a bit painful merge after 1.3.1 release and I also found your typescript branch :)
So if you like it I will do some refactoring and rewrite to TS.
Test plan
New tests were added, old tests still work except one test with invalid code and two tests that check dependency extraction during evaluation.