📜 ⬆️ ⬇️

How I migrated the project from Angular 1 to React

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.


Not holivar sake


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.


Project


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.


What happened


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.


Get down to business


"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


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:



 <!--  --> <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> 


 <!--  --> <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



Why Typescript Compiler API


  1. The controller can be written in TypeScript
  2. We want to get at the output of the React component on TypeScript with the generated interfaces State and Props.

There are no miracles


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.


What became



Whats ahead



I hope you enjoyed it and I helped someone save time in the refactoring process;)


')

Source: https://habr.com/ru/post/358964/


All Articles