Hello!
I want to share my experience and tools that I used to migrate the project from Angular 1 to React .
TLTR: I wrote a module with which you can transform Angular components (controller + template) into React components.
In this article, I will not prove why and which framework is better. Yes, besides React there is Vue, Angular 6 has already been released, and also Ember, Svelte and many others ... In general, I want to tell you how I solved the task, I hope my experience and practices will be useful to someone.
Each may have their own reasons for switching to another framework / library. In my company, the main project was written when React was still walking under the table quite a long time, for this was chosen Angular 1.x. Sometimes he brought pain (digest cycle, magic with votcher and Angulyarovskim promises), but in general he did his job.
In all new related projects, including the mobile version of the main project, the Redux + React + Typescript + CSS Modules bundle is used. As a result, there appeared its own library of components, styles, all projects are strictly standardized, the development of new components and subprojects has accelerated significantly.
The main project continued to live in parallel on Angular and required more and more time for support, because you can't just take and use ready-made code I had to solve the already solved problems again, write components from scratch. Especially on the horizon, the prospect of combining the main and mobile versions of the project into one project with an adaptive layout.
Yes, there is ngReact , but there was no particular desire to turn the project into a kind of Frankenstein monster. Therefore, it was decided to move the project to React to simplify its development and support.
Main project
Related projects and mobile version
I note that most of the entire business logic (validators, sending requests, utilities, etc.) was implemented separately on Typescript as NPM modules, which makes it easy to reuse code between projects regardless of the framework.
"I love routine and refactoring!" - no developer in the world
I think many would agree that refactoring is not the most interesting thing. Therefore, I decided to partially automate this process.
Even superficially comparing the components of React and Angular, one can derive (of course a strongly simplified) formula:
React.Component = Angular Controller + Angular Directive + Angular Template;
So it turned out ng2react-builder
You, probably, already understood that I am the master of giving names to the modules. Well, not about that ...
What module can do
It is best to see an example from the documentation , and even better examples of components in test cases .
We can feed our module and the controller to the module (directives are still in the span), and the output will be the assembled React component (React.PureComponent or React.Component) with JSX markup.
Without a controller, we can easily assemble a simple, stateless component (React.StatelessComponent).
ng2react-builder Attempts to convert all Angular expressions to valid JS / JSX constructs:
ng-repeat
we will get a native JS'ny .map()
with JSX output <!-- --> <div> <span ng-repeat="item in list as | limitTo:5 as results">{{item.name}}</span> </div> <!-- --> <div> {results.slice(0, 5).map((item, index) => { return <span key={`child-${ index }`}>{item.name}</span> })} </div>
{{expression}}
content will be converted to {expression}
<!-- --> <a ng-click="$event.preventDefault(); selectItem(item)">{{item.name}}</a> <my-icon="calendar"><my-icon/>
// ng2rect-builder' directivesToTags: { 'my-icon': { tagName: 'MyReactIcon', valueProp: 'type' } }
<!-- --> <a onClick={(event) => { event.preventDefault(); selectItem(item); }}> {item.name} </a> <MyReactIcon type="calendar"/>
Another particularly useful thing is the ability to translate directives into a call to a JS function (only directives specified as an attribute are currently supported):
<!-- --> <span my-directive="some.value"></span>
// ng2rect-builder' directivesToTextNodes: { myDirective: { callee: 'myFunc', calleeArguments: ['arg1'] } }
<!-- --> <span>{myFunc(arg1, 'some.value')}</span>
How it works
render
method is added with the resulting JSX template.Why Typescript Compiler API
Alas. As I have not tried.
As I wrote above, I’ll have to take a file and continue refactoring manually, but this module saved me a lot of time on routine tasks, especially in translating Angular templates to JSX.
I hope you enjoyed it and I helped someone save time in the refactoring process;)
Source: https://habr.com/ru/post/358964/
All Articles