Repository: teleporthq/teleport-code-generators
Pull request #478 (2020-08-13 11:05:50)

feat(core): importing and using it as reference for nodes
fixes #478 #474 

TODO

- [x] Import and use as attribute reference
- [x] Import and use as a direct node.
- [x] Use case for just import alone (Used for importing external css libraries) (Ideally while importing from certain design systems, we don't need to use this import in every single file. So, this need to be added only on the *root* node level. Ideally where we define our router)
- [x] Fix dependencies that are specified in the *root* node doesn't reflect in `package.json` file. 
- [x] Remap elementNames if the dependency is coming from external Import and need to have a alias name. Related to #474 

Checks 

- [x] Check the support for JSX based Generators like React, Preact, Stencil
- [x] Check support for HTML based Generators like Vue, Angular

Tests

- [x] Update test cases for all the new features that are being added.

JayaKrishnaNamburu: Ensure all the frameworks support the basic requirements of using external components.

- [ ] NextJS all it's `css` dependencies inside `_app` file instead of the `index` or router where we usually import
codecov[bot]: # [Codecov](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/478?src=pr&el=h1) Report
> :exclamation: No coverage uploaded for pull request base (`development@9847d8c`). [Click here to learn what that means](https://docs.codecov.io/docs/error-reference#section-missing-base-commit).
> The diff coverage is `45.97%`.

[![Impacted file tree graph](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/478/graphs/tree.svg?width=650&height=150&src=pr&token=LI2WPEFm1R)](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/478?src=pr&el=tree)

```diff
@@              Coverage Diff               @@
##             development     #478   +/-   ##
==============================================
  Coverage               ?   77.62%           
==============================================
  Files                  ?      156           
  Lines                  ?     5452           
  Branches               ?     1132           
==============================================
  Hits                   ?     4232           
  Misses                 ?     1166           
  Partials               ?       54           
```


| [Impacted Files](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/478?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [...ort-component-generator/src/assembly-line/utils.ts](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/478/diff?src=pr&el=tree#diff-cGFja2FnZXMvdGVsZXBvcnQtY29tcG9uZW50LWdlbmVyYXRvci9zcmMvYXNzZW1ibHktbGluZS91dGlscy50cw==) | `28.57% <0.00%> (ø)` | |
| [...-common/src/node-handlers/node-to-jsx/constants.ts](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/478/diff?src=pr&el=tree#diff-cGFja2FnZXMvdGVsZXBvcnQtcGx1Z2luLWNvbW1vbi9zcmMvbm9kZS1oYW5kbGVycy9ub2RlLXRvLWpzeC9jb25zdGFudHMudHM=) | `100.00% <ø> (ø)` | |
| [...teleport-plugin-preact-base-component/src/index.ts](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/478/diff?src=pr&el=tree#diff-cGFja2FnZXMvdGVsZXBvcnQtcGx1Z2luLXByZWFjdC1iYXNlLWNvbXBvbmVudC9zcmMvaW5kZXgudHM=) | `96.55% <ø> (ø)` | |
| [.../teleport-plugin-react-base-component/src/index.ts](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/478/diff?src=pr&el=tree#diff-cGFja2FnZXMvdGVsZXBvcnQtcGx1Z2luLXJlYWN0LWJhc2UtY29tcG9uZW50L3NyYy9pbmRleC50cw==) | `96.42% <ø> (ø)` | |
| [...eleport-plugin-stencil-base-component/src/index.ts](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/478/diff?src=pr&el=tree#diff-cGFja2FnZXMvdGVsZXBvcnQtcGx1Z2luLXN0ZW5jaWwtYmFzZS1jb21wb25lbnQvc3JjL2luZGV4LnRz) | `84.21% <ø> (ø)` | |
| [...es/teleport-plugin-vue-base-component/src/index.ts](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/478/diff?src=pr&el=tree#diff-cGFja2FnZXMvdGVsZXBvcnQtcGx1Z2luLXZ1ZS1iYXNlLWNvbXBvbmVudC9zcmMvaW5kZXgudHM=) | `93.33% <ø> (ø)` | |
| [...kages/teleport-project-generator-nuxt/src/index.ts](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/478/diff?src=pr&el=tree#diff-cGFja2FnZXMvdGVsZXBvcnQtcHJvamVjdC1nZW5lcmF0b3ItbnV4dC9zcmMvaW5kZXgudHM=) | `100.00% <ø> (ø)` | |
| [packages/teleport-uidl-resolver/src/utils.ts](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/478/diff?src=pr&el=tree#diff-cGFja2FnZXMvdGVsZXBvcnQtdWlkbC1yZXNvbHZlci9zcmMvdXRpbHMudHM=) | `58.96% <0.00%> (ø)` | |
| [...t-uidl-validator/src/decoders/component-decoder.ts](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/478/diff?src=pr&el=tree#diff-cGFja2FnZXMvdGVsZXBvcnQtdWlkbC12YWxpZGF0b3Ivc3JjL2RlY29kZXJzL2NvbXBvbmVudC1kZWNvZGVyLnRz) | `100.00% <ø> (ø)` | |
| [...ages/teleport-uidl-validator/src/decoders/utils.ts](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/478/diff?src=pr&el=tree#diff-cGFja2FnZXMvdGVsZXBvcnQtdWlkbC12YWxpZGF0b3Ivc3JjL2RlY29kZXJzL3V0aWxzLnRz) | `96.15% <ø> (ø)` | |
| ... and [166 more](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/478/diff?src=pr&el=tree-more) | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/478?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/478?src=pr&el=footer). Last update [9847d8c...a476e40](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/478?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/package.json b/package.json
index ba8fca2f..4ae9eb03 100755
--- a/package.json
+++ b/package.json
@@ -24,8 +24,9 @@
     "changelog": "lerna-changelog",
     "version": "lerna version",
     "publish": "lerna publish from-package",
-    "local:publish": "lerna exec -- npm publish --registry http://localhost:4873",
-    "local:unpublish": "lerna exec -- npm unpublish -f --registry http://localhost:4873"
+    "local:adduser": "npm adduser --registry http://localhost:4873",
+    "local:publish": "lerna exec --bail=false  -- npm publish -f --registry http://localhost:4873",
+    "local:unpublish": "lerna exec --bail=false -- npm unpublish -f --registry http://localhost:4873"
   },
   "husky": {
     "hooks": {
diff --git a/packages/teleport-component-generator/src/assembly-line/index.ts b/packages/teleport-component-generator/src/assembly-line/index.ts
index 43220374..44ee68ef 100644
--- a/packages/teleport-component-generator/src/assembly-line/index.ts
+++ b/packages/teleport-component-generator/src/assembly-line/index.ts
@@ -1,10 +1,11 @@
-import { extractExternalDependencies, groupChunksByFileType } from './utils'
+import { groupChunksByFileType } from './utils'
 import {
   ComponentStructure,
   ComponentPlugin,
   ComponentUIDL,
   GeneratorOptions,
 } from '@teleporthq/teleport-types'
+import { UIDLUtils } from '@teleporthq/teleport-shared'
 
 export default class AssemblyLine {
   private plugins: ComponentPlugin[]
@@ -33,7 +34,10 @@ export default class AssemblyLine {
       Promise.resolve(structure)
     )
 
-    const externalDependencies = extractExternalDependencies(finalStructure.dependencies)
+    const externalDependencies = {
+      ...UIDLUtils.extractExternalDependencies(finalStructure.dependencies),
+      ...UIDLUtils.extractExternalDependencies(finalStructure.uidl?.peerDefinitions || {}),
+    }
     const chunks = groupChunksByFileType(finalStructure.chunks)
 
     return {
diff --git a/packages/teleport-component-generator/src/assembly-line/utils.ts b/packages/teleport-component-generator/src/assembly-line/utils.ts
index 9258ff11..1fef3b44 100644
--- a/packages/teleport-component-generator/src/assembly-line/utils.ts
+++ b/packages/teleport-component-generator/src/assembly-line/utils.ts
@@ -1,19 +1,4 @@
-import { UIDLDependency, ChunkDefinition } from '@teleporthq/teleport-types'
-
-export const extractExternalDependencies = (dependencies: Record<string, UIDLDependency>) => {
-  return Object.keys(dependencies)
-    .filter((key) => {
-      return dependencies[key].type === 'package'
-    })
-    .reduce((acc: Record<string, string>, key) => {
-      const depInfo = dependencies[key]
-      if (depInfo.path && (depInfo.type === 'library' || depInfo.type === 'package')) {
-        acc[depInfo.path] = depInfo.version
-      }
-
-      return acc
-    }, {})
-}
+import { ChunkDefinition } from '@teleporthq/teleport-types'
 
 export const groupChunksByFileType = (
   chunks: ChunkDefinition[]
diff --git a/packages/teleport-plugin-angular-base-component/src/utils.ts b/packages/teleport-plugin-angular-base-component/src/utils.ts
index 3b802ea1..3ca35554 100644
--- a/packages/teleport-plugin-angular-base-component/src/utils.ts
+++ b/packages/teleport-plugin-angular-base-component/src/utils.ts
@@ -24,6 +24,8 @@ export const generateExportAST = (
     angularMethodsAST = createMethodsObject(methodsObject, propDefinitions)
   }
 
+  const { importDefinitions = {} } = uidl
+
   const propDeclaration = Object.keys(propDefinitions).map((propKey) => {
     const definition = propDefinitions[propKey]
     // By default any prop with type function is used to emitting events to the callee
@@ -64,11 +66,19 @@ export const generateExportAST = (
     )
   })
 
+  const referencedImportDeclarations = Object.keys(importDefinitions).reduce((acc, importRef) => {
+    if (!importDefinitions[importRef]?.meta?.importJustPath) {
+      acc.push(t.classProperty(t.identifier(importRef), t.identifier(importRef)))
+    }
+    return acc
+  }, [])
+
   const classBodyAST = (componentUIDL: ComponentUIDL) => {
     return t.classBody([
       ...propDeclaration,
       ...propertyDecleration,
       ...dataDeclaration,
+      ...referencedImportDeclarations,
       constructorAST(componentUIDL.seo),
       ...angularMethodsAST,
     ])
diff --git a/packages/teleport-plugin-angular-module/src/index.ts b/packages/teleport-plugin-angular-module/src/index.ts
index 71d9ba5d..f4bb29b3 100644
--- a/packages/teleport-plugin-angular-module/src/index.ts
+++ b/packages/teleport-plugin-angular-module/src/index.ts
@@ -5,6 +5,7 @@ import {
   ComponentPlugin,
   ChunkType,
   FileType,
+  UIDLDependency,
 } from '@teleporthq/teleport-types'
 
 import {
@@ -17,6 +18,8 @@ import {
   createComponentModuleDecorator,
   createPageModuleModuleDecorator,
   constructRouteForComponentsModule,
+  extractExtrenalImportsFromComponents,
+  extractExternalDependenciesFromPage,
 } from './utils'
 
 import {
@@ -46,17 +49,19 @@ export const createAngularModulePlugin: ComponentPluginFactory<AngularRoutingCon
   } = config || {}
 
   const angularModuleGenerator: ComponentPlugin = async (structure) => {
-    const { uidl, dependencies, chunks, options } = structure
+    const { uidl, chunks, options, dependencies } = structure
     const { stateDefinitions = {} } = uidl
 
-    const { moduleComponents } = options
+    const { moduleComponents = {} } = options
 
     let routesAST: types.VariableDeclaration
     let ngModuleAST: types.Decorator
     let moduleDecoratorAST: types.ExportNamedDeclaration
+    let externalDependencies: Record<string, UIDLDependency> = {}
 
     dependencies.NgModule = ANGULAR_CORE_DEPENDENCY
     dependencies.RouterModule = ANGULAR_ROUTER
+
     switch (moduleType) {
       case 'root':
         {
@@ -79,7 +84,13 @@ export const createAngularModulePlugin: ComponentPluginFactory<AngularRoutingCon
           dependencies[componentName] = constructLocalDependency(fileName)
 
           routesAST = createPageRouteAST(componentName)
-          ngModuleAST = createPageModuleModuleDecorator(componentName)
+
+          externalDependencies = extractExternalDependenciesFromPage(uidl)
+
+          ngModuleAST = createPageModuleModuleDecorator(
+            componentName,
+            Object.keys(externalDependencies)
+          )
           moduleDecoratorAST = createExportModuleAST(uidl.outputOptions.moduleName)
 
           // Acording to widely followed convention module should have .module in its name
@@ -105,7 +116,13 @@ export const createAngularModulePlugin: ComponentPluginFactory<AngularRoutingCon
           const componentClassNames = Object.keys(moduleComponents).map((componentKey) =>
             UIDLUtils.getComponentClassName(moduleComponents[componentKey])
           )
-          ngModuleAST = createComponentModuleDecorator(componentClassNames)
+
+          externalDependencies = extractExtrenalImportsFromComponents(moduleComponents)
+
+          ngModuleAST = createComponentModuleDecorator(
+            componentClassNames,
+            Object.keys(externalDependencies)
+          )
           moduleDecoratorAST = createExportModuleAST('ComponentsModule')
         }
         break
@@ -113,6 +130,12 @@ export const createAngularModulePlugin: ComponentPluginFactory<AngularRoutingCon
         throw new Error(`Invalid module type '${moduleType}'`)
     }
 
+    if (Object.keys(externalDependencies).length > 0) {
+      Object.keys(externalDependencies).forEach((importRef) => {
+        dependencies[importRef] = externalDependencies[importRef]
+      })
+    }
+
     // Routes will be present for only pages and root
     if (routesAST) {
       chunks.push({
diff --git a/packages/teleport-plugin-angular-module/src/utils.ts b/packages/teleport-plugin-angular-module/src/utils.ts
index 39f9a6b7..b600048f 100644
--- a/packages/teleport-plugin-angular-module/src/utils.ts
+++ b/packages/teleport-plugin-angular-module/src/utils.ts
@@ -3,15 +3,21 @@ import {
   UIDLDependency,
   UIDLConditionalNode,
   UIDLStateDefinition,
+  ComponentUIDL,
 } from '@teleporthq/teleport-types'
-import { StringUtils } from '@teleporthq/teleport-shared'
+import { StringUtils, UIDLUtils } from '@teleporthq/teleport-shared'
 
-export const createPageModuleModuleDecorator = (componentName: string, t = types) => {
+export const createPageModuleModuleDecorator = (
+  componentName: string,
+  externalComponents: string[] = [],
+  t = types
+) => {
   const imports: types.ObjectProperty = t.objectProperty(
     t.identifier('imports'),
     t.arrayExpression([
       t.identifier('CommonModule'),
       t.identifier('ComponentsModule'),
+      ...externalComponents.map((component) => t.identifier(component)),
       t.callExpression(t.memberExpression(t.identifier('RouterModule'), t.identifier('forChild')), [
         t.identifier('routes'),
       ]),
@@ -35,7 +41,11 @@ export const createPageModuleModuleDecorator = (componentName: string, t = types
   )
 }
 
-export const createComponentModuleDecorator = (componentNames?: string[], t = types) => {
+export const createComponentModuleDecorator = (
+  componentNames?: string[],
+  externalComponents: string[] = [],
+  t = types
+) => {
   const componentsList =
     componentNames && componentNames.length > 0
       ? componentNames.map((componentName) => t.identifier(componentName))
@@ -48,7 +58,11 @@ export const createComponentModuleDecorator = (componentNames?: string[], t = ty
 
   const imports: types.ObjectProperty = t.objectProperty(
     t.identifier('imports'),
-    t.arrayExpression([t.identifier('CommonModule'), t.identifier('RouterModule')])
+    t.arrayExpression([
+      ...externalComponents.map((componentName) => t.identifier(componentName)),
+      t.identifier('CommonModule'),
+      t.identifier('RouterModule'),
+    ])
   )
 
   const exportsProperty: types.ObjectProperty = t.objectProperty(
@@ -63,7 +77,7 @@ export const createComponentModuleDecorator = (componentNames?: string[], t = ty
   )
 }
 
-export const createRootModuleDecorator = (t = types) => {
+export const createRootModuleDecorator = (externalComponents: string[] = [], t = types) => {
   const declerations: types.ObjectProperty = t.objectProperty(
     t.identifier('declarations'),
     t.arrayExpression([t.identifier('AppComponent')])
@@ -77,6 +91,7 @@ export const createRootModuleDecorator = (t = types) => {
         t.identifier('routes'),
       ]),
       t.identifier('ComponentsModule'),
+      ...externalComponents.map((component) => t.identifier(component)),
     ])
   )
 
@@ -192,3 +207,50 @@ export const constructRouteForComponentsModule = (path: string) => {
   }
   return dependency
 }
+
+export const extractExternalDependenciesFromPage = (uidl: ComponentUIDL) => {
+  const extractedDependencies: Record<string, UIDLDependency> = {}
+  return traverseUIDLElements(uidl, extractedDependencies)
+}
+
+// In Angular imports are not added to components, instead they are added to modules
+export const extractExtrenalImportsFromComponents = (
+  components: Record<string, ComponentUIDL>
+): Record<string, UIDLDependency> => {
+  const externalDependencies: Record<string, UIDLDependency> = {}
+  if (Object.keys(components).length > 0) {
+    Object.values(components).forEach((component) => {
+      traverseUIDLElements(component, externalDependencies)
+    })
+  }
+  return externalDependencies
+}
+
+const traverseUIDLElements = (
+  component: ComponentUIDL,
+  dependenciesMap: Record<string, UIDLDependency>
+): Record<string, UIDLDependency> => {
+  UIDLUtils.traverseElements(component.node, (element) => {
+    const { dependency, semanticType, elementType } = element
+    const elementTag = semanticType || elementType
+    if (dependency?.type === 'package') {
+      const existingDependency = dependenciesMap[elementTag]
+
+      if (existingDependency) {
+        const safeImport = `${StringUtils.dashCaseToUpperCamelCase(
+          StringUtils.removeIllegalCharacters(dependency.path)
+        )}${elementTag}`
+        dependenciesMap[safeImport] = {
+          ...dependency,
+          meta: {
+            ...dependency.meta,
+            originalName: safeImport,
+          },
+        }
+      } else {
+        dependenciesMap[elementTag] = dependency
+      }
+    }
+  })
+  return dependenciesMap
+}
diff --git a/packages/teleport-plugin-common/src/node-handlers/node-to-html/index.ts b/packages/teleport-plugin-common/src/node-handlers/node-to-html/index.ts
index c7c5f439..894e92f3 100644
--- a/packages/teleport-plugin-common/src/node-handlers/node-to-html/index.ts
+++ b/packages/teleport-plugin-common/src/node-handlers/node-to-html/index.ts
@@ -17,25 +17,44 @@ const generateElementNode: NodeToHTML<UIDLElementNode, HastNode> = (node, params
   const templateSyntax = { ...DEFAULT_TEMPLATE_SYNTAX, ...syntax }
   const { dependencies, templateLookup } = params
   const { elementType, name, key, children, attrs, dependency, events, selfClosing } = node.content
-  const tagName = elementType || 'component'
-  const safeTagName =
+
+  const originalElementName = elementType || 'component'
+  const tagName = originalElementName
+  let safeTagName =
     dependency && dependency.type === 'local'
       ? templateSyntax.customElementTagName(tagName)
       : tagName
 
-  const htmlNode = createHTMLNode(safeTagName)
-
-  if (dependency && templateSyntax.dependencyHandling === 'import') {
-    if (dependency.type !== 'local') {
-      // library and package dependencies are assumed to be safe
-      dependencies[tagName] = { ...dependency }
-    } else {
+  if (dependency) {
+    const existingDependency = dependencies[tagName]
+    safeTagName =
+      existingDependency && existingDependency?.path !== dependency?.path
+        ? `${StringUtils.dashCaseToUpperCamelCase(
+            StringUtils.removeIllegalCharacters(dependency.path)
+          )}${tagName}`
+        : tagName
+
+    if (templateSyntax.dependencyHandling === 'import' && dependency.type !== 'local') {
+      dependencies[safeTagName] = { ...dependency }
+
+      if (existingDependency && existingDependency?.path !== dependency?.path) {
+        dependencies[safeTagName] = {
+          ...dependency,
+          meta: {
+            ...dependency.meta,
+            originalName: originalElementName,
+          },
+        }
+      }
+    } else if (dependency.type === 'local') {
       // local dependencies can be renamed based on their safety (eg: Header/header, Form/form)
       const safeImportName = StringUtils.dashCaseToUpperCamelCase(safeTagName)
       dependencies[safeImportName] = { ...dependency }
     }
   }
 
+  const htmlNode = createHTMLNode(safeTagName)
+
   if (attrs) {
     Object.keys(attrs).forEach((attrKey) => {
       const attrValue = attrs[attrKey]
diff --git a/packages/teleport-plugin-common/src/node-handlers/node-to-html/utils.ts b/packages/teleport-plugin-common/src/node-handlers/node-to-html/utils.ts
index 254a61a4..68e03df0 100644
--- a/packages/teleport-plugin-common/src/node-handlers/node-to-html/utils.ts
+++ b/packages/teleport-plugin-common/src/node-handlers/node-to-html/utils.ts
@@ -23,6 +23,7 @@ export const handleAttribute = (
   const dynamicAttrKey = templateSyntax.valueBinding(attrKey, node)
   switch (attrValue.type) {
     case 'dynamic':
+    case 'import':
       hastUtils.addAttributeToNode(htmlNode, dynamicAttrKey, attrValue.content.id)
       break
     case 'static':
diff --git a/packages/teleport-plugin-common/src/node-handlers/node-to-jsx/index.ts b/packages/teleport-plugin-common/src/node-handlers/node-to-jsx/index.ts
index 534c3d8c..7b117bee 100644
--- a/packages/teleport-plugin-common/src/node-handlers/node-to-jsx/index.ts
+++ b/packages/teleport-plugin-common/src/node-handlers/node-to-jsx/index.ts
@@ -39,7 +39,30 @@ const generateElementNode: NodeToJSX<UIDLElementNode, types.JSXElement> = (
   const { dependencies, nodesLookup } = params
   const { elementType, selfClosing, children, key, attrs, dependency, events } = node.content
 
-  const tagName = elementType || 'component'
+  const originalElementName = elementType || 'component'
+  let tagName = originalElementName
+
+  if (dependency) {
+    if (options.dependencyHandling === 'import') {
+      const existingDependency = dependencies[tagName]
+      if (existingDependency && existingDependency?.path !== dependency?.path) {
+        tagName = `${StringUtils.dashCaseToUpperCamelCase(
+          StringUtils.removeIllegalCharacters(dependency.path)
+        )}${tagName}`
+        dependencies[tagName] = {
+          ...dependency,
+          meta: {
+            ...dependency.meta,
+            originalName: originalElementName,
+          },
+        }
+      } else {
+        // Make a copy to avoid reference leaking
+        dependencies[tagName] = { ...dependency }
+      }
+    }
+  }
+
   const elementName =
     dependency && dependency.type === 'local' && options.customElementTag
       ? options.customElementTag(tagName)
@@ -58,6 +81,9 @@ const generateElementNode: NodeToJSX<UIDLElementNode, types.JSXElement> = (
             options.dynamicReferencePrefixMap[referenceType as 'prop' | 'state' | 'local']
           addDynamicAttributeToJSXTag(elementTag, attrKey, id, prefix)
           break
+        case 'import':
+          addDynamicAttributeToJSXTag(elementTag, attrKey, attributeValue.content.id)
+          break
         case 'static':
           const { content } = attributeValue
           addAttributeToJSXTag(elementTag, attrKey, content)
@@ -72,13 +98,6 @@ const generateElementNode: NodeToJSX<UIDLElementNode, types.JSXElement> = (
     })
   }
 
-  if (dependency) {
-    if (options.dependencyHandling === 'import') {
-      // Make a copy to avoid reference leaking
-      dependencies[tagName] = { ...dependency }
-    }
-  }
-
   if (events) {
     Object.keys(events).forEach((eventKey) => {
       addEventHandlerToTag(elementTag, eventKey, events[eventKey], params, options)
diff --git a/packages/teleport-plugin-import-statements/src/index.ts b/packages/teleport-plugin-import-statements/src/index.ts
index 9b2698c4..966c219d 100644
--- a/packages/teleport-plugin-import-statements/src/index.ts
+++ b/packages/teleport-plugin-import-statements/src/index.ts
@@ -7,15 +7,19 @@ import {
   ImportIdentifier,
   ChunkType,
   FileType,
+  ComponentStructure,
 } from '@teleporthq/teleport-types'
 
 interface ImportPluginConfig {
   importLibsChunkName?: string
   importPackagesChunkName?: string
   importLocalsChunkName?: string
+  fileType?: FileType
 }
 
-export const createImportPlugin: ComponentPluginFactory<ImportPluginConfig> = (config) => {
+export const createImportPlugin: ComponentPluginFactory<ImportPluginConfig> = (
+  config: ImportPluginConfig
+) => {
   const {
     importLibsChunkName = 'import-lib',
     importPackagesChunkName = 'import-pack',
@@ -23,12 +27,39 @@ export const createImportPlugin: ComponentPluginFactory<ImportPluginConfig> = (c
     fileType = FileType.JS,
   } = config || {}
 
-  const importPlugin: ComponentPlugin = async (structure) => {
-    const { dependencies } = structure
+  const importPlugin: ComponentPlugin = async (structure: ComponentStructure) => {
+    const { uidl, dependencies } = structure
+    let collectedDependencies = dependencies
+
+    if (uidl?.importDefinitions) {
+      const { importDefinitions = {} } = uidl
+      collectedDependencies = {
+        ...collectedDependencies,
+        ...importDefinitions,
+      }
+      if (Object.keys(importDefinitions).length > 0) {
+        Object.keys(importDefinitions).forEach((dependencyRef) => {
+          const dependency = importDefinitions[dependencyRef]
+          if (dependency.meta?.useAsReference || dependency.meta?.importJustPath) {
+            return
+          }
+          dependencies[dependencyRef] = {
+            type: 'package',
+            path: dependency.meta?.importJustPath ? dependency.path : dependencyRef,
+            version: dependency.version,
+            meta: {
+              importJustPath: dependency?.meta?.importJustPath,
+              originalName: dependency?.meta?.originalName,
+              namedImport: dependency?.meta?.namedImport,
+            },
+          }
+        })
+      }
+    }
 
-    const libraryDependencies = groupDependenciesByPackage(dependencies, 'library')
-    const packageDependencies = groupDependenciesByPackage(dependencies, 'package')
-    const localDependencies = groupDependenciesByPackage(dependencies, 'local')
+    const libraryDependencies = groupDependenciesByPackage(collectedDependencies, 'library')
+    const packageDependencies = groupDependenciesByPackage(collectedDependencies, 'package')
+    const localDependencies = groupDependenciesByPackage(collectedDependencies, 'local')
     addImportChunk(structure.chunks, libraryDependencies, importLibsChunkName, fileType)
     addImportChunk(structure.chunks, packageDependencies, importPackagesChunkName, fileType)
     addImportChunk(structure.chunks, localDependencies, importLocalsChunkName, fileType)
diff --git a/packages/teleport-plugin-react-jss/src/utils.ts b/packages/teleport-plugin-react-jss/src/utils.ts
index 5b6c1057..8cbfbe50 100644
--- a/packages/teleport-plugin-react-jss/src/utils.ts
+++ b/packages/teleport-plugin-react-jss/src/utils.ts
@@ -1,9 +1,9 @@
 import * as t from '@babel/types'
 import { UIDLUtils } from '@teleporthq/teleport-shared'
 import { ParsedASTNode, ASTBuilders } from '@teleporthq/teleport-plugin-common'
-import { UIDLAttributeValue } from '@teleporthq/teleport-types'
+import { UIDLStyleValue } from '@teleporthq/teleport-types'
 
-export const generatePropSyntax = (style: Record<string, UIDLAttributeValue>) => {
+export const generatePropSyntax = (style: Record<string, UIDLStyleValue>) => {
   return UIDLUtils.transformDynamicStyles(style, (styleValue) => {
     if (styleValue.content.referenceType === 'prop') {
       return new ParsedASTNode(
diff --git a/packages/teleport-plugin-react-styled-components/src/utils.ts b/packages/teleport-plugin-react-styled-components/src/utils.ts
index 76e5b0dc..ddc65db3 100644
--- a/packages/teleport-plugin-react-styled-components/src/utils.ts
+++ b/packages/teleport-plugin-react-styled-components/src/utils.ts
@@ -1,12 +1,7 @@
 import * as t from '@babel/types'
 import { StringUtils, UIDLUtils } from '@teleporthq/teleport-shared'
 import { ASTUtils } from '@teleporthq/teleport-plugin-common'
-import {
-  UIDLStyleValue,
-  UIDLDependency,
-  UIDLAttributeValue,
-  UIDLReferencedStyles,
-} from '@teleporthq/teleport-types'
+import { UIDLStyleValue, UIDLDependency, UIDLReferencedStyles } from '@teleporthq/teleport-types'
 
 export const generateStyledComponent = (
   name: string,
@@ -114,7 +109,7 @@ export const removeUnusedDependencies = (
 }
 
 export const generatePropReferencesSyntax = (
-  style: Record<string, UIDLAttributeValue>,
+  style: Record<string, UIDLStyleValue>,
   timesReferred: number,
   root: t.JSXElement,
   propsPrefix: unknown
diff --git a/packages/teleport-plugin-react-styled-jsx/src/index.ts b/packages/teleport-plugin-react-styled-jsx/src/index.ts
index 982bdce7..0cd5d20b 100644
--- a/packages/teleport-plugin-react-styled-jsx/src/index.ts
+++ b/packages/teleport-plugin-react-styled-jsx/src/index.ts
@@ -1,10 +1,6 @@
 import { StringUtils, UIDLUtils } from '@teleporthq/teleport-shared'
 import { ASTUtils, StyleBuilders, ASTBuilders } from '@teleporthq/teleport-plugin-common'
-import {
-  ComponentPluginFactory,
-  ComponentPlugin,
-  UIDLAttributeValue,
-} from '@teleporthq/teleport-types'
+import { ComponentPluginFactory, ComponentPlugin, UIDLStyleValue } from '@teleporthq/teleport-types'
 import { generateStyledJSXTag } from './utils'
 import * as types from '@babel/types'
 
@@ -31,7 +27,7 @@ export const createReactStyledJSXPlugin: ComponentPluginFactory<StyledJSXConfig>
     const mediaStylesMap: Record<string, Record<string, unknown>> = {}
     const styleJSXString: string[] = []
 
-    const transformStyle = (style: Record<string, UIDLAttributeValue>) =>
+    const transformStyle = (style: Record<string, UIDLStyleValue>) =>
       UIDLUtils.transformDynamicStyles(style, (styleValue) => {
         if (styleValue.content.referenceType === 'prop') {
           return `\$\{${propsPrefix}.${styleValue.content.id}\}`
diff --git a/packages/teleport-plugin-vue-base-component/src/index.ts b/packages/teleport-plugin-vue-base-component/src/index.ts
index 61569623..7fe370a2 100644
--- a/packages/teleport-plugin-vue-base-component/src/index.ts
+++ b/packages/teleport-plugin-vue-base-component/src/index.ts
@@ -30,7 +30,6 @@ export const createVueComponentPlugin: ComponentPluginFactory<VueComponentConfig
 
   const vueComponentPlugin: ComponentPlugin = async (structure) => {
     const { uidl, chunks, dependencies } = structure
-
     const templateLookup: { [key: string]: unknown } = {}
     const dataObject: Record<string, unknown> = {}
     const methodsObject: Record<string, UIDLEventHandlerStatement[]> = {}
@@ -72,6 +71,7 @@ export const createVueComponentPlugin: ComponentPluginFactory<VueComponentConfig
     })
 
     const stateObject = uidl.stateDefinitions ? extractStateObject(uidl.stateDefinitions) : {}
+
     const jsContent = generateVueComponentJS(
       uidl,
       Object.keys(dependencies),
diff --git a/packages/teleport-plugin-vue-base-component/src/utils.ts b/packages/teleport-plugin-vue-base-component/src/utils.ts
index ae961c59..997d094e 100644
--- a/packages/teleport-plugin-vue-base-component/src/utils.ts
+++ b/packages/teleport-plugin-vue-base-component/src/utils.ts
@@ -25,6 +25,8 @@ export const generateVueComponentJS = (
 ) => {
   const vueObjectProperties = []
 
+  const { importDefinitions = {} } = uidl
+
   if (uidl.propDefinitions) {
     const props = createVuePropsDefinition(uidl.propDefinitions)
     const propsAST = ASTUtils.objectToObjectExpression(props)
@@ -45,8 +47,15 @@ export const generateVueComponentJS = (
     vueObjectProperties.push(t.objectProperty(t.identifier('components'), componentsAST))
   }
 
-  if (Object.keys(dataObject).length > 0) {
+  if (Object.keys(dataObject).length > 0 || Object.keys(importDefinitions).length > 0) {
     const dataAST = ASTUtils.objectToObjectExpression(dataObject)
+
+    Object.keys(importDefinitions).forEach((importRef) => {
+      if (!importDefinitions[importRef].meta?.importJustPath) {
+        dataAST.properties.push(t.objectProperty(t.identifier(importRef), t.identifier(importRef)))
+      }
+    })
+
     vueObjectProperties.push(
       t.objectMethod(
         'method',
diff --git a/packages/teleport-project-generator-next/src/index.ts b/packages/teleport-project-generator-next/src/index.ts
index e2d25287..3cd89e88 100644
--- a/packages/teleport-project-generator-next/src/index.ts
+++ b/packages/teleport-project-generator-next/src/index.ts
@@ -72,6 +72,10 @@ const createNextProjectGenerator = () => {
         configContentGenerator,
         isGlobalStylesDependent: true,
       },
+      externalStyles: {
+        fileName: '_app',
+        fileType: FileType.JS,
+      },
     },
     static: {
       prefix: '',
diff --git a/packages/teleport-project-generator-next/src/utils.ts b/packages/teleport-project-generator-next/src/utils.ts
index 0c348e0f..25a8d3a5 100644
--- a/packages/teleport-project-generator-next/src/utils.ts
+++ b/packages/teleport-project-generator-next/src/utils.ts
@@ -124,33 +124,42 @@ export const configContentGenerator = (options: FrameWorkConfigOptions, t = type
     dependencies: options.dependencies,
   }
 
-  if (options.globalStyles?.isGlobalStylesDependent) {
-    const contentChunkContent = t.exportDefaultDeclaration(
-      t.functionDeclaration(
-        t.identifier('MyApp'),
-        [
-          t.objectPattern([
-            t.objectProperty(t.identifier('Component'), t.identifier('Component')),
-            t.objectProperty(t.identifier('pageProps'), t.identifier('pageProps')),
-          ]),
-        ],
-        t.blockStatement([
-          t.returnStatement(
-            t.jsxElement(
-              t.jsxOpeningElement(
-                t.jsxIdentifier('Component'),
-                [t.jsxSpreadAttribute(t.identifier('pageProps'))],
-                true
-              ),
-              null,
-              [],
+  const contentChunkContent = t.exportDefaultDeclaration(
+    t.functionDeclaration(
+      t.identifier('MyApp'),
+      [
+        t.objectPattern([
+          t.objectProperty(t.identifier('Component'), t.identifier('Component')),
+          t.objectProperty(t.identifier('pageProps'), t.identifier('pageProps')),
+        ]),
+      ],
+      t.blockStatement([
+        t.returnStatement(
+          t.jsxElement(
+            t.jsxOpeningElement(
+              t.jsxIdentifier('Component'),
+              [t.jsxSpreadAttribute(t.identifier('pageProps'))],
               true
-            )
-          ),
-        ])
-      )
+            ),
+            null,
+            [],
+            true
+          )
+        ),
+      ])
     )
+  )
+
+  chunks.push({
+    type: ChunkType.AST,
+    name: 'app-js-chunk',
+    fileType: FileType.JS,
+    content: contentChunkContent,
+    linkAfter: ['import-js-chunk'],
+  })
 
+  // Adding global styles import only when needed. By default we will generate _app.js
+  if (options.globalStyles?.isGlobalStylesDependent) {
     chunks.push({
       type: ChunkType.AST,
       name: 'import-js-chunk',
@@ -161,18 +170,10 @@ export const configContentGenerator = (options: FrameWorkConfigOptions, t = type
       ),
       linkAfter: [],
     })
+  }
 
-    chunks.push({
-      type: ChunkType.AST,
-      name: 'app-js-chunk',
-      fileType: FileType.JS,
-      content: contentChunkContent,
-      linkAfter: ['import-js-chunk'],
-    })
-
-    result.chunks = {
-      [FileType.JS]: chunks,
-    }
+  result.chunks = {
+    [FileType.JS]: chunks,
   }
 
   return result
diff --git a/packages/teleport-project-generator-nuxt/src/index.ts b/packages/teleport-project-generator-nuxt/src/index.ts
index cab47e42..ca30d76a 100644
--- a/packages/teleport-project-generator-nuxt/src/index.ts
+++ b/packages/teleport-project-generator-nuxt/src/index.ts
@@ -58,11 +58,11 @@ const createNuxtProjectGenerator = () => {
     },
     framework: {
       config: {
-        generator: configGenerator,
-        configContentGenerator,
         fileName: 'nuxt.config',
         fileType: FileType.JS,
         path: [''],
+        generator: configGenerator,
+        configContentGenerator,
         isGlobalStylesDependent: true,
       },
     },
diff --git a/packages/teleport-project-generator/package.json b/packages/teleport-project-generator/package.json
index 0fdf852c..652e8e2c 100644
--- a/packages/teleport-project-generator/package.json
+++ b/packages/teleport-project-generator/package.json
@@ -30,7 +30,9 @@
     "@teleporthq/teleport-shared": "^0.12.4",
     "@teleporthq/teleport-types": "^0.12.4",
     "@teleporthq/teleport-uidl-builders": "^0.12.4",
-    "@teleporthq/teleport-uidl-validator": "^0.12.4"
+    "@teleporthq/teleport-uidl-validator": "^0.12.4",
+    "@teleporthq/teleport-plugin-import-statements": "^0.12.4",
+    "@teleporthq/teleport-component-generator": "^0.12.4"
   },
   "gitHead": "b185c3fdb7dc94ff8c7eed63f7edba055fffa8d0"
 }
diff --git a/packages/teleport-project-generator/src/file-handlers.ts b/packages/teleport-project-generator/src/file-handlers.ts
index 092129a3..b3a231ab 100644
--- a/packages/teleport-project-generator/src/file-handlers.ts
+++ b/packages/teleport-project-generator/src/file-handlers.ts
@@ -55,8 +55,7 @@ export const createComponentModule = async (uidl: ProjectUIDL, strategy: Project
   root.outputOptions = root.outputOptions || {}
   root.outputOptions.fileName = 'components.module'
 
-  const { files } = await moduleGenerator.generateComponent(root, options)
-  return files[0]
+  return moduleGenerator.generateComponent(root, options)
 }
 
 export const createPageModule = async (
@@ -86,8 +85,9 @@ export const createRouterFile = async (root: ComponentUIDL, strategy: ProjectStr
   root.outputOptions = root.outputOptions || {}
   root.outputOptions.fileName = fileName || DEFAULT_ROUTER_FILE_NAME
 
-  const { files } = await routerGenerator.generateComponent(root, options)
-  return files[0]
+  const { files, dependencies } = await routerGenerator.generateComponent(root, options)
+
+  return { routerFile: files[0], dependencies }
 }
 
 export const createEntryFile = async (
diff --git a/packages/teleport-project-generator/src/index.ts b/packages/teleport-project-generator/src/index.ts
index c354982a..d3438930 100644
--- a/packages/teleport-project-generator/src/index.ts
+++ b/packages/teleport-project-generator/src/index.ts
@@ -3,6 +3,8 @@ import {
   resolveLocalDependencies,
   createPageUIDLs,
   prepareComponentOutputOptions,
+  generateExternalCSSImports,
+  fileFileAndReplaceContent,
 } from './utils'
 
 import {
@@ -33,6 +35,7 @@ import {
   ComponentGenerator,
   ProjectStrategyPageOptions,
   ConfigGeneratorResult,
+  GeneratedFile,
 } from '@teleporthq/teleport-types'
 
 type UpdateGeneratorCallback = (generator: ComponentGenerator) => void
@@ -121,6 +124,10 @@ export class ProjectGenerator {
     mapping: Mapping = {}
   ): Promise<GeneratedFolder> {
     let cleanedUIDL = input
+    const inMemoryFilesMap = new Map<
+      string,
+      { rootFolder: GeneratedFolder; path: string[]; files: GeneratedFile[] }
+    >()
     // Validating and parsing the UIDL
     const schemaValidationResult = this.validator.validateProjectSchema(input)
     const { valid, projectUIDL } = schemaValidationResult
@@ -167,9 +174,15 @@ export class ProjectGenerator {
     // Handling project style sheet
     if (this.strategy.projectStyleSheet?.generator && Object.keys(styleSetDefinitions).length > 0) {
       const { generator, path } = this.strategy.projectStyleSheet
-      const { files } = await generator.generateComponent(uidl.root)
+      const { files, dependencies } = await generator.generateComponent(uidl.root)
 
-      injectFilesToPath(rootFolder, path, files)
+      inMemoryFilesMap.set('projectStyleSheet', {
+        rootFolder,
+        path,
+        files,
+      })
+
+      collectedDependencies = { ...collectedDependencies, ...dependencies }
     }
 
     // Handling pages
@@ -197,20 +210,44 @@ export class ProjectGenerator {
       }
 
       const { files, dependencies } = await createPage(pageUIDL, this.strategy, pageOptions)
-
       // Pages might be generated inside subfolders in the main pages folder
       const relativePath = UIDLUtils.getComponentFolderPath(pageUIDL)
       const path = this.strategy.pages.path.concat(relativePath)
 
-      injectFilesToPath(rootFolder, path, files)
+      inMemoryFilesMap.set(pageUIDL.name, {
+        rootFolder,
+        path,
+        files,
+      })
+
       collectedDependencies = { ...collectedDependencies, ...dependencies }
 
       if (this.strategy.pages.moduleGenerator) {
         const pageModule = await createPageModule(pageUIDL, this.strategy, options)
-        injectFilesToPath(rootFolder, path, pageModule.files)
+
+        inMemoryFilesMap.set(`${pageUIDL.name}Module`, {
+          rootFolder,
+          path,
+          files: pageModule.files,
+        })
+
+        collectedDependencies = { ...collectedDependencies, ...pageModule.dependencies }
       }
     }
 
+    // Handling module generation for components
+    if (this.strategy.components.moduleGenerator) {
+      const componentsModule = await createComponentModule(uidl, this.strategy)
+
+      inMemoryFilesMap.set(componentsModule.files[0].name, {
+        rootFolder,
+        path: this.strategy.components.path,
+        files: componentsModule.files,
+      })
+
+      collectedDependencies = { ...collectedDependencies, ...componentsModule.dependencies }
+    }
+
     // Handling components
     for (const componentName of Object.keys(components)) {
       let componentOptions = options
@@ -246,14 +283,13 @@ export class ProjectGenerator {
       const relativePath = UIDLUtils.getComponentFolderPath(componentUIDL)
       const path = this.strategy.components.path.concat(relativePath)
 
-      injectFilesToPath(rootFolder, path, files)
-      collectedDependencies = { ...collectedDependencies, ...dependencies }
-    }
+      inMemoryFilesMap.set(componentName, {
+        rootFolder,
+        path,
+        files,
+      })
 
-    // Handling module generation for components
-    if (this.strategy.components.moduleGenerator) {
-      const componentsModuleFile = await createComponentModule(uidl, this.strategy)
-      injectFilesToPath(rootFolder, this.strategy.components.path, [componentsModuleFile])
+      collectedDependencies = { ...collectedDependencies, ...dependencies }
     }
 
     // Handling framework specific changes to the project
@@ -274,7 +310,12 @@ export class ProjectGenerator {
           fileType
         )
         collectedDependencies = result.dependencies
-        injectFilesToPath(rootFolder, this.strategy.framework.replace.path, [result.file])
+
+        inMemoryFilesMap.set(fileName, {
+          rootFolder,
+          path: this.strategy.framework.replace.path,
+          files: [result.file],
+        })
       }
     }
 
@@ -309,7 +350,11 @@ export class ProjectGenerator {
             framework.config.fileName
           )
 
-          injectFilesToPath(rootFolder, this.strategy.framework.config.path, files)
+          inMemoryFilesMap.set(fileName, {
+            rootFolder,
+            path: this.strategy.framework.config.path,
+            files,
+          })
         }
       }
     }
@@ -317,21 +362,63 @@ export class ProjectGenerator {
     // Global settings are transformed into the root html file and the manifest file for PWA support
     if (uidl.globals.manifest) {
       const manifestFile = createManifestJSONFile(uidl, assetsPrefix)
-      injectFilesToPath(rootFolder, this.strategy.static.path, [manifestFile])
+
+      inMemoryFilesMap.set(manifestFile.name, {
+        rootFolder,
+        path: this.strategy.static.path,
+        files: [manifestFile],
+      })
     }
 
+    // TODO: Projects which don't need a router file will miss collecting
+    // dependencies which are specified on them
+
     // Create the routing component in case the project generator has a strategy for that
     if (this.strategy.router) {
-      const routerFile = await createRouterFile(root, this.strategy)
-      injectFilesToPath(rootFolder, this.strategy.router.path, [routerFile])
+      const { routerFile, dependencies } = await createRouterFile(root, this.strategy)
+
+      inMemoryFilesMap.set('router', {
+        rootFolder,
+        path: this.strategy.router.path,
+        files: [routerFile],
+      })
+
+      collectedDependencies = { ...collectedDependencies, ...dependencies }
     }
 
     // Create the entry file of the project (ex: index.html, _document.js)
     if (this.strategy.entry) {
       const entryFile = await createEntryFile(uidl, this.strategy, { assetsPrefix })
-      injectFilesToPath(rootFolder, this.strategy.entry.path, [entryFile])
+      inMemoryFilesMap.set('entry', {
+        rootFolder,
+        path: this.strategy.entry.path,
+        files: [entryFile],
+      })
+    }
+
+    // If the framework needs all the external css dependencies to be placed in some other file
+    if (framework?.externalStyles && this.strategy.pages.options?.useFileNameForNavigation) {
+      const { fileName } = framework.externalStyles
+      const folder = inMemoryFilesMap.get(fileName)
+
+      if (!folder) {
+        throw new Error(`Canno't find file - ${fileName} from the list of files generated`)
+      }
+
+      const [resultFile] = await generateExternalCSSImports(uidl.root)
+      const files = fileFileAndReplaceContent(folder.files, fileName, resultFile.content)
+
+      inMemoryFilesMap.set(fileName, {
+        rootFolder,
+        path: folder.path,
+        files,
+      })
     }
 
+    inMemoryFilesMap.forEach((stage) => {
+      injectFilesToPath(stage.rootFolder, stage.path, stage.files)
+    })
+
     // Inject all the collected dependencies in the package.json file
     handlePackageJSON(rootFolder, uidl, collectedDependencies)
 
diff --git a/packages/teleport-project-generator/src/utils.ts b/packages/teleport-project-generator/src/utils.ts
index 67462a68..f6ceb64e 100644
--- a/packages/teleport-project-generator/src/utils.ts
+++ b/packages/teleport-project-generator/src/utils.ts
@@ -11,9 +11,13 @@ import {
   UIDLStateDefinition,
   UIDLPageOptions,
   UIDLComponentOutputOptions,
+  UIDLExternalDependency,
 } from '@teleporthq/teleport-types'
 import { elementNode } from '@teleporthq/teleport-uidl-builders'
 
+import importStatementsPlugin from '@teleporthq/teleport-plugin-import-statements'
+import { createComponentGenerator } from '@teleporthq/teleport-component-generator'
+
 export const createPageUIDLs = (uidl: ProjectUIDL, strategy: ProjectStrategy): ComponentUIDL[] => {
   const routeNodes = UIDLUtils.extractRoutes(uidl.root)
   return routeNodes.map((routeNode) => createPageUIDL(routeNode, uidl, strategy))
@@ -26,10 +30,11 @@ const createPageUIDL = (
 ): ComponentUIDL => {
   const { value, node } = routeNode.content
   const pageName = value.toString()
+
   const routeDefinition = uidl.root.stateDefinitions.route
   const pagesStrategyOptions = strategy.pages.options || {}
 
-  const pageOptions = extractPageOptions(
+  const { pageOptions, isHomePage } = extractPageOptions(
     routeDefinition,
     pageName,
     pagesStrategyOptions.useFileNameForNavigation
@@ -84,12 +89,38 @@ const createPageUIDL = (
   // The solution is to wrap a non-element node with a 'group' element
   const pageContent = node.type === 'element' ? node : elementNode('group', {}, [node])
 
-  return {
+  const componentUIDL: ComponentUIDL = {
     name: componentName,
     node: pageContent,
     outputOptions,
     seo,
   }
+
+  /* Adding all kinds of peer dependencies and importing css only files
+   are good to be added in router. So, for projects which don't follow that
+   We will use since we don't generate any router */
+
+  /* Fow now frameworks which follow file name for navigation
+   have such constaraints like placing all css imports in some other files */
+  if (isHomePage && strategy.pages?.options?.useFileNameForNavigation) {
+    const { importDefinitions = {} } = uidl.root
+
+    componentUIDL.importDefinitions = Object.keys(importDefinitions).reduce(
+      (acc: Record<string, UIDLExternalDependency>, importRef) => {
+        if (
+          strategy.framework?.externalStyles &&
+          importDefinitions[importRef].path.endsWith('.css')
+        ) {
+          return acc
+        }
+        acc[importRef] = importDefinitions[importRef]
+        return acc
+      },
+      {}
+    )
+  }
+
+  return componentUIDL
 }
 
 /**
@@ -101,7 +132,7 @@ export const extractPageOptions = (
   routeDefinitions: UIDLStateDefinition,
   routeName: string,
   useFileNameForNavigation = false
-): UIDLPageOptions => {
+): { pageOptions: UIDLPageOptions; isHomePage: boolean } => {
   const isHomePage = routeDefinitions.defaultValue === routeName
   const pageDefinitions = routeDefinitions.values || []
   const pageDefinition = pageDefinitions.find((stateDef) => stateDef.value === routeName)
@@ -140,7 +171,7 @@ export const extractPageOptions = (
     otherPages.map((page) => page.pageOptions)
   )
 
-  return pageOptions
+  return { pageOptions, isHomePage }
 }
 
 export const prepareComponentOutputOptions = (
@@ -383,6 +414,45 @@ export const generateLocalDependenciesPrefix = (fromPath: string[], toPath: stri
   return dependencyPrefix
 }
 
+export const fileFileAndReplaceContent = (
+  files: GeneratedFile[],
+  fileName: string,
+  content: string
+): GeneratedFile[] => {
+  Object.values(files).forEach((file: GeneratedFile) => {
+    if (file.name === fileName) {
+      file.content = content.concat(file.content)
+    }
+  })
+  return files
+}
+
+export const generateExternalCSSImports = async (uidl: ComponentUIDL) => {
+  const { importDefinitions = {} } = uidl
+
+  const styleImports = Object.keys(importDefinitions || {}).reduce(
+    (acc: Record<string, UIDLExternalDependency>, importRef) => {
+      const importedPackage = importDefinitions[importRef]
+      if (importedPackage.path.endsWith('.css')) {
+        acc[importRef] = importDefinitions[importRef]
+        return acc
+      }
+      return acc
+    },
+    {}
+  )
+
+  const generator = createComponentGenerator()
+  const { chunks } = await importStatementsPlugin({
+    uidl: null,
+    dependencies: styleImports,
+    options: {},
+    chunks: [],
+  })
+
+  return generator.linkCodeChunks({ imports: chunks }, 'imports')
+}
+
 const removeCommonStartingPointsFromPaths = (paths: string[][]): string[][] => {
   const pathsClone: string[][] = JSON.parse(JSON.stringify(paths))
 
diff --git a/packages/teleport-shared/src/utils/uidl-utils.ts b/packages/teleport-shared/src/utils/uidl-utils.ts
index ce792d13..2a34d7d9 100644
--- a/packages/teleport-shared/src/utils/uidl-utils.ts
+++ b/packages/teleport-shared/src/utils/uidl-utils.ts
@@ -16,6 +16,8 @@ import {
   UIDLRepeatContent,
   UIDLRepeatMeta,
   UIDLElementNode,
+  UIDLDependency,
+  UIDLStyleValue,
 } from '@teleporthq/teleport-types'
 
 export const extractRoutes = (rootComponent: ComponentUIDL) => {
@@ -188,6 +190,7 @@ export const traverseNodes = (
 
     case 'static':
     case 'dynamic':
+    case 'import':
     case 'raw':
       break
 
@@ -386,7 +389,7 @@ export const transformDynamicStyles = (
  */
 export const transformStringAssignmentToJson = (
   declaration: string | number
-): UIDLStaticValue | UIDLAttributeValue => {
+): UIDLStaticValue | UIDLStyleValue => {
   if (typeof declaration === 'number') {
     return {
       type: 'static',
@@ -437,7 +440,7 @@ export const transformStylesAssignmentsToJson = (
       const { type } = styleContentAtKey as Record<string, unknown>
 
       if (['dynamic', 'static'].indexOf(type as string) !== -1) {
-        acc[key] = styleContentAtKey as UIDLAttributeValue
+        acc[key] = styleContentAtKey as UIDLStyleValue
         return acc
       }
 
@@ -475,7 +478,7 @@ export const transformAttributesAssignmentsToJson = (
     if (!Array.isArray(attributeContent) && entityType === 'object') {
       // if this value is already properly declared, make sure it is not
       const { type } = attributeContent as Record<string, unknown>
-      if (['dynamic', 'static'].indexOf(type as string) !== -1) {
+      if (['dynamic', 'static', 'import'].indexOf(type as string) !== -1) {
         acc[key] = attributeContent as UIDLAttributeValue
         return acc
       }
@@ -559,3 +562,18 @@ export const removeChildNodes = (
       )
   }
 }
+
+export const extractExternalDependencies = (dependencies: Record<string, UIDLDependency>) => {
+  return Object.keys(dependencies)
+    .filter((key) => {
+      return dependencies[key].type === 'package'
+    })
+    .reduce((acc: Record<string, string>, key) => {
+      const depInfo = dependencies[key]
+      if (depInfo.path && depInfo.type === 'package') {
+        acc[depInfo.path] = depInfo.version
+      }
+
+      return acc
+    }, {})
+}
diff --git a/packages/teleport-types/src/generators.ts b/packages/teleport-types/src/generators.ts
index 4ec9962b..afa94987 100644
--- a/packages/teleport-types/src/generators.ts
+++ b/packages/teleport-types/src/generators.ts
@@ -181,6 +181,11 @@ export interface ProjectStrategy {
       configContentGenerator?: (options: FrameWorkConfigOptions) => ConfigGeneratorResult
       isGlobalStylesDependent?: boolean
     }
+    externalStyles?: {
+      // All the css imports from importDefinitions are moved to the file in this destination
+      fileName: string
+      fileType: string
+    }
     replace?: {
       fileName: string
       fileType: string
diff --git a/packages/teleport-types/src/uidl.ts b/packages/teleport-types/src/uidl.ts
index ff2d46a5..1d43fdba 100755
--- a/packages/teleport-types/src/uidl.ts
+++ b/packages/teleport-types/src/uidl.ts
@@ -1,5 +1,4 @@
 export interface ProjectUIDL {
-  $schema?: string
   name: string
   globals: UIDLGlobalProjectValues
   root: ComponentUIDL
@@ -40,6 +39,8 @@ export interface ComponentUIDL {
   node: UIDLElementNode
   styleSetDefinitions?: Record<string, UIDLStyleSetDefinition>
   propDefinitions?: Record<string, UIDLPropDefinition>
+  importDefinitions?: Record<string, UIDLExternalDependency>
+  peerDefinitions?: Record<string, UIDLPeerDependency>
   stateDefinitions?: Record<string, UIDLStateDefinition>
   outputOptions?: UIDLComponentOutputOptions
   seo?: UIDLComponentSEO
@@ -195,15 +196,23 @@ export type UIDLNode =
   | UIDLElementNode
   | UIDLConditionalNode
   | UIDLSlotNode
+  | UIDLImportReference
 
-export type UIDLAttributeValue = UIDLDynamicReference | UIDLStaticValue
+export type UIDLAttributeValue = UIDLDynamicReference | UIDLStaticValue | UIDLImportReference
 
-export type UIDLStyleValue = UIDLAttributeValue
+export type UIDLStyleValue = UIDLDynamicReference | UIDLStaticValue
 
 export type UIDLStyleDefinitions = Record<string, UIDLStyleValue>
 
 export type UIDLEventDefinitions = Record<string, UIDLEventHandlerStatement[]>
 
+export interface UIDLImportReference {
+  type: 'import'
+  content: {
+    id: string
+  }
+}
+
 export interface UIDLURLLinkNode {
   type: 'url'
   content: {
@@ -251,6 +260,12 @@ export interface UIDLEventHandlerStatement {
 
 export type UIDLDependency = UIDLLocalDependency | UIDLExternalDependency
 
+export interface UIDLPeerDependency {
+  type: 'package'
+  path: string
+  version: string
+}
+
 export interface UIDLLocalDependency {
   type: 'local'
   path?: string
@@ -269,6 +284,7 @@ export interface UIDLExternalDependency {
     namedImport?: boolean
     originalName?: string
     importJustPath?: boolean
+    useAsReference?: boolean
   }
 }
 
@@ -314,7 +330,7 @@ export interface UIDLElementNodeInlineReferencedStyle {
   content: {
     mapType: 'inlined'
     conditions: UIDLStyleConditions[]
-    styles: Record<string, UIDLAttributeValue>
+    styles: Record<string, UIDLStyleValue>
   }
 }
 
diff --git a/packages/teleport-uidl-resolver/src/utils.ts b/packages/teleport-uidl-resolver/src/utils.ts
index c80692b8..cee2269c 100644
--- a/packages/teleport-uidl-resolver/src/utils.ts
+++ b/packages/teleport-uidl-resolver/src/utils.ts
@@ -91,7 +91,7 @@ export const resolveElement = (element: UIDLElement, options: GeneratorOptions)
   const originalElement = element
   const originalElementType = originalElement.elementType
   const mappedElement = elementsMapping[originalElement.elementType] || {
-    elementType: originalElement.elementType, // identity mapping
+    elementType: originalElement.semanticType ?? originalElement.elementType, // identity mapping
   }
 
   // Setting up the name of the node based on the type, if it is not supplied
diff --git a/packages/teleport-uidl-validator/src/decoders/component-decoder.ts b/packages/teleport-uidl-validator/src/decoders/component-decoder.ts
index cd53e676..dd48de32 100644
--- a/packages/teleport-uidl-validator/src/decoders/component-decoder.ts
+++ b/packages/teleport-uidl-validator/src/decoders/component-decoder.ts
@@ -14,6 +14,8 @@ import {
   outputOptionsDecoder,
   elementNodeDecoder,
   componentSeoDecoder,
+  externaldependencyDecoder,
+  peerDependencyDecoder,
 } from './utils'
 
 const componentUIDLValudator: Decoder<VComponentUIDL> = object({
@@ -24,6 +26,8 @@ const componentUIDLValudator: Decoder<VComponentUIDL> = object({
   stateDefinitions: optional(dict(stateDefinitionsDecoder)),
   styleSetDefinitions: optional(dict(styleSetDefinitionDecoder)),
   propDefinitions: optional(dict(propDefinitionsDecoder)),
+  peerDefinitions: optional(dict(peerDependencyDecoder)),
+  importDefinitions: optional(dict(externaldependencyDecoder)),
   outputOptions: optional(outputOptionsDecoder),
   seo: optional(componentSeoDecoder),
 })
diff --git a/packages/teleport-uidl-validator/src/decoders/utils.ts b/packages/teleport-uidl-validator/src/decoders/utils.ts
index daacf4b1..277f4694 100644
--- a/packages/teleport-uidl-validator/src/decoders/utils.ts
+++ b/packages/teleport-uidl-validator/src/decoders/utils.ts
@@ -38,6 +38,7 @@ import {
   UIDLGlobalAsset,
   UIDLExternalDependency,
   UIDLLocalDependency,
+  UIDLPeerDependency,
 } from '@teleporthq/teleport-types'
 import {
   VUIDLStyleSetDefnition,
@@ -56,6 +57,7 @@ import {
   VUIDLStyleSetStateCondition,
 } from './types'
 import { CustomCombinators } from './custom-combinators'
+import { UIDLImportReference } from '@teleporthq/teleport-types/src'
 
 const {
   isValidComponentName,
@@ -202,6 +204,12 @@ export const outputOptionsDecoder: Decoder<UIDLComponentOutputOptions> = object(
   folderPath: optional(array((isValidFileName() as unknown) as Decoder<string>)),
 })
 
+export const peerDependencyDecoder: Decoder<UIDLPeerDependency> = object({
+  type: constant('package'),
+  version: string(),
+  path: string(),
+})
+
 export const externaldependencyDecoder: Decoder<UIDLExternalDependency> = object({
   type: union(constant('library'), constant('package')),
   path: string(),
@@ -211,6 +219,7 @@ export const externaldependencyDecoder: Decoder<UIDLExternalDependency> = object
       namedImport: optional(boolean()),
       originalName: optional(string()),
       importJustPath: optional(boolean()),
+      useAsReference: optional(boolean()),
     })
   ),
 })
@@ -232,12 +241,23 @@ export const dependencyDecoder: Decoder<UIDLDependency> = union(
   externaldependencyDecoder
 )
 
+export const importReferenceDecoder: Decoder<UIDLImportReference> = object({
+  type: constant('import'),
+  content: object({
+    id: string(),
+  }),
+})
+
 export const attributeValueDecoder: Decoder<UIDLAttributeValue> = union(
   dynamicValueDecoder,
-  staticValueDecoder
+  staticValueDecoder,
+  importReferenceDecoder
 )
 
-export const styleValueDecoder: Decoder<UIDLStyleValue> = attributeValueDecoder
+export const styleValueDecoder: Decoder<UIDLStyleValue> = union(
+  staticValueDecoder,
+  dynamicValueDecoder
+)
 
 export const styleDefinitionsDecoder: Decoder<UIDLStyleDefinitions> = dict(styleValueDecoder)
 
diff --git a/packages/teleport-uidl-validator/src/validator/utils.ts b/packages/teleport-uidl-validator/src/validator/utils.ts
index e61798a4..c53636a8 100644
--- a/packages/teleport-uidl-validator/src/validator/utils.ts
+++ b/packages/teleport-uidl-validator/src/validator/utils.ts
@@ -7,15 +7,17 @@ import {
   UIDLNode,
   UIDLStyleSetDefinition,
   UIDLStaticValue,
+  UIDLExternalDependency,
 } from '@teleporthq/teleport-types'
 
 // Prop definitions and state definitions should have different keys
 export const checkForDuplicateDefinitions = (input: ComponentUIDL) => {
   const props = Object.keys(input.propDefinitions || {})
   const states = Object.keys(input.stateDefinitions || {})
+  const imports = Object.keys(input.importDefinitions || {})
 
   props
-    .filter((x) => states.includes(x))
+    .filter((x) => states.includes(x) || imports.includes(x))
     .forEach((duplicate) =>
       console.warn(
         `\n"${duplicate}" is defined both as a prop and as a state. If you are using VUE Code Generators this can cause bad behavior.`
@@ -63,15 +65,31 @@ const validLocalVariableUsage = (dynamicId: string, repeatIteratorName: string)
   return dynamicIdRoot === iteratorName
 }
 
-// All referenced props and states should be previously defined in the
-// "propDefinitions" and "stateDefinitions" sections
-// If props or states are defined and not used, a warning witll be displayed
+/* All referenced props, states and importRefs should be previously defined in the
+ "propDefinitions" and "stateDefinitions" and "importDefinitions" sections
+ If props or states are defined and not used, a warning witll be displayed */
 export const checkDynamicDefinitions = (input: Record<string, unknown>) => {
   const propKeys = Object.keys(input.propDefinitions || {})
   const stateKeys = Object.keys(input.stateDefinitions || {})
+  let importKeys = Object.keys(input.importDefinitions || {})
+
+  const importDefinitions: { [key: string]: UIDLExternalDependency } = ((input?.importDefinitions ??
+    {}) as unknown) as { [key: string]: UIDLExternalDependency }
+
+  if (Object.keys(importKeys).length > 0) {
+    importKeys = importKeys.reduce((acc, importRef) => {
+      if (importDefinitions[importRef]?.meta?.importJustPath) {
+        return acc
+      }
+
+      acc.push(importRef)
+      return acc
+    }, [])
+  }
 
   const usedPropKeys: string[] = []
   const usedStateKeys: string[] = []
+  const usedImportKeys: string[] = []
   const errors: string[] = []
 
   UIDLUtils.traverseNodes(input.node as UIDLNode, (node) => {
@@ -98,6 +116,18 @@ export const checkDynamicDefinitions = (input: Record<string, unknown>) => {
       const dynamicIdRoot = node.content.id.split('.')[0]
       usedStateKeys.push(dynamicIdRoot)
     }
+
+    if (node.type === 'import') {
+      if (!dynamicPathExistsInDefinitions(node.content.id, importKeys)) {
+        const errorMsg = `\n"${node.content.id}" is used but not defined. Please add it in importDefinitions`
+        errors.push(errorMsg)
+      }
+
+      // for member expression we check the root
+      // if value has no `.` it will be checked as it is
+      const dynamicIdRoot = node.content.id.split('.')[0]
+      usedImportKeys.push(dynamicIdRoot)
+    }
   })
 
   propKeys
@@ -112,6 +142,12 @@ export const checkDynamicDefinitions = (input: Record<string, unknown>) => {
       console.warn(`"${diff}" is defined in stateDefinitions but it is not used in the UIDL.`)
     )
 
+  importKeys
+    .filter((x) => !usedImportKeys.includes(x))
+    .forEach((diff) =>
+      console.warn(`"${diff}" is defined in importDefinitions but it is not used in the UIDL.`)
+    )
+
   return errors
 }
 
diff --git a/yarn.lock b/yarn.lock
index 80ef6eca..e43854a2 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -6806,8 +6806,9 @@ pretty-quick@^2.0.1:
     multimatch "^4.0.0"
 
 prismjs@^1.14.0, prismjs@^1.17.1:
-  version "1.19.0"
-  resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.19.0.tgz#713afbd45c3baca4b321569f2df39e17e729d4dc"
+  version "1.21.0"
+  resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.21.0.tgz#36c086ec36b45319ec4218ee164c110f9fc015a3"
+  integrity sha512-uGdSIu1nk3kej2iZsLyDoJ7e9bnPzIgY0naW/HdknGj61zScaprVEVGHrPoXqI+M9sP0NDnTK2jpkvmldpuqDw==
   optionalDependencies:
     clipboard "^2.0.0"
 


Test patch:
diff --git a/packages/teleport-component-generator-angular/__tests__/integration/component-dependency.ts b/packages/teleport-component-generator-angular/__tests__/integration/component-dependency.ts
new file mode 100644
index 00000000..a7e73fe1
--- /dev/null
+++ b/packages/teleport-component-generator-angular/__tests__/integration/component-dependency.ts
@@ -0,0 +1,26 @@
+import { createAngularComponentGenerator } from '../../src'
+import { GeneratedFile } from '@teleporthq/teleport-types'
+import componentJSON from './component-with-smilar-element-name-depependencies.json'
+
+const generator = createAngularComponentGenerator()
+
+const TS_FILE = 'ts'
+const HTML_FILE = 'html'
+const findFileByType = (files: GeneratedFile[], type: string = TS_FILE) =>
+  files.find((file) => file.fileType === type)
+
+describe('Component Dependencies', () => {
+  it('Imports and re-maps component dependencies if there are any duplicates', async () => {
+    const result = await generator.generateComponent(componentJSON)
+    const tsFile = findFileByType(result.files, TS_FILE)
+    const htmlFile = findFileByType(result.files, HTML_FILE)
+
+    expect(tsFile).toBeDefined()
+    expect(htmlFile).toBeDefined()
+    expect(htmlFile.content).toContain(`[tokens]="tokens" [components]="components"`)
+    expect(tsFile.content).toContain(`import { tokens, components } from 'react-ui'`)
+    expect(tsFile.content).toContain(`tokens = tokens`)
+    expect(tsFile.content).toContain(`components = components`)
+    expect(tsFile.content).not.toContain(`antdCSS = antdCSS`)
+  })
+})
diff --git a/packages/teleport-component-generator-angular/__tests__/integration/component-with-smilar-element-name-depependencies.json b/packages/teleport-component-generator-angular/__tests__/integration/component-with-smilar-element-name-depependencies.json
new file mode 100644
index 00000000..6c098ae3
--- /dev/null
+++ b/packages/teleport-component-generator-angular/__tests__/integration/component-with-smilar-element-name-depependencies.json
@@ -0,0 +1,117 @@
+{
+    "name": "App",
+    "importDefinitions": {
+      "tokens": {
+        "type": "package",
+        "path": "react-ui",
+        "version": "1.0.0-beta.26",
+        "meta": {
+          "namedImport": true
+        }
+      },
+      "components": {
+        "path": "react-ui",
+        "type": "package",
+        "version": "1.0.0-beta.26",
+        "meta": {
+          "namedImport": true
+        }
+      },
+      "antdCSS": {
+        "path": "antd/dist/antd.css",
+        "type": "package",
+        "version": "4.5.1",
+        "meta": {
+          "importJustPath": true
+        }
+      }
+    },
+    "node": {
+      "type": "element",
+      "content": {
+        "semanticType": "ThemeProvider",
+        "elementType": "component",
+        "attrs": {
+          "tokens": {
+            "type": "import",
+            "content": {
+              "id": "tokens"
+            }
+          },
+          "components": {
+            "type": "import",
+            "content": {
+              "id": "components"
+            }
+          }
+        },
+        "dependency": {
+          "type": "package",
+          "path": "react-ui",
+          "version": "1.0.0-beta.26",
+          "meta": {
+            "namedImport": true
+          }
+        },
+        "children": [
+          {
+            "type": "element",
+            "content": {
+              "semanticType": "Button",
+              "elementType": "component",
+              "attrs": {
+                "variant": "primary"
+              },
+              "children": ["Button from Chakra"],
+              "dependency": {
+                "type": "package",
+                "path": "react-ui",
+                "version": "1.0.0-beta.26",
+                "meta": {
+                  "namedImport": true
+                }
+              }
+            }
+          },
+          {
+            "type": "element",
+            "content": {
+              "semanticType": "Avatar",
+              "elementType": "component",
+              "attrs": {
+                "size": "xlarge",
+                "src": "https://github.com/sameen-shi.png"
+              },
+              "dependency": {
+                "type": "package",
+                "path": "react-ui",
+                "version": "1.0.0-beta.26",
+                "meta": {
+                  "namedImport": true
+                }
+              }
+            }
+          },
+          {
+            "type": "element",
+            "content": {
+              "semanticType": "Button",
+              "elementType": "component",
+              "attrs": {
+                "type": "primary"
+              },
+              "children": ["Button from ANTD"],
+              "dependency": {
+                "type": "package",
+                "path": "antd",
+                "version": "0.8.0",
+                "meta": {
+                  "namedImport": true
+                }
+              }
+            }
+          }
+        ]
+      }
+    }
+  }
\ No newline at end of file
diff --git a/packages/teleport-component-generator-react/__tests__/integration/component-dependency.ts b/packages/teleport-component-generator-react/__tests__/integration/component-dependency.ts
index 7f4106f7..50c409b3 100644
--- a/packages/teleport-component-generator-react/__tests__/integration/component-dependency.ts
+++ b/packages/teleport-component-generator-react/__tests__/integration/component-dependency.ts
@@ -1,5 +1,6 @@
 import { createReactComponentGenerator } from '../../src'
 import { GeneratedFile } from '@teleporthq/teleport-types'
+import componentJSON from './component-with-smilar-element-name-depependencies.json'
 
 import {
   component,
@@ -54,6 +55,18 @@ describe('Component with dependency ', () => {
       expect(jsFile.content).toContain("import ReactDatepicker from 'react-datepicker'")
     })
 
+    it('Remaps elementName when to elements have same name but different dependencies', async () => {
+      const result = await generator.generateComponent(componentJSON)
+      const jsFile = findFileByType(result.files, JS_FILE)
+
+      expect(jsFile).toBeDefined()
+      expect(jsFile.content).toContain(
+        `import { ThemeProvider, Button, Avatar, tokens, components } from 'react-ui`
+      )
+      expect(jsFile.content).toContain(`import { Button as AntdButton } from 'antd'`)
+      expect(jsFile.content).toContain(`import 'antd/dist/antd.css'`)
+    })
+
     it('renders code with named import ', async () => {
       const result = await generator.generateComponent(
         uidl(
diff --git a/packages/teleport-component-generator-react/__tests__/integration/component-import-definitions.ts b/packages/teleport-component-generator-react/__tests__/integration/component-import-definitions.ts
new file mode 100644
index 00000000..f0a05888
--- /dev/null
+++ b/packages/teleport-component-generator-react/__tests__/integration/component-import-definitions.ts
@@ -0,0 +1,19 @@
+import { createReactComponentGenerator } from '../../src'
+import { GeneratedFile, FileType } from '@teleporthq/teleport-types'
+import componentJSON from './component-with-import-definitions.json'
+
+const findFileByType = (files: GeneratedFile[], type: string = FileType.JS) =>
+  files.find((file) => file.fileType === type)
+
+describe('Generates component and uses importDefinitions', () => {
+  it('Generates component and uses importDefinitions', async () => {
+    const generator = createReactComponentGenerator()
+    const { files } = await generator.generateComponent(componentJSON)
+    const jsFile = findFileByType(files, FileType.JS)
+
+    expect(jsFile.content).toContain(
+      `import { ThemeProvider, Button, theme as defaultTheme } from '@chakra-ui/core'`
+    )
+    expect(jsFile.content).toContain(`<ThemeProvider theme={defaultTheme}>`)
+  })
+})
diff --git a/packages/teleport-component-generator-react/__tests__/integration/component-with-import-definitions.json b/packages/teleport-component-generator-react/__tests__/integration/component-with-import-definitions.json
new file mode 100644
index 00000000..6e4fb6c3
--- /dev/null
+++ b/packages/teleport-component-generator-react/__tests__/integration/component-with-import-definitions.json
@@ -0,0 +1,58 @@
+{
+    "name": "App",
+    "importDefinitions": {
+      "defaultTheme": {
+        "type": "package",
+        "path": "@chakra-ui/core",
+        "version": "0.8.0",
+        "meta": {
+          "namedImport": true,
+          "originalName": "theme"
+        }
+      }
+    },
+    "node": {
+      "type": "element",
+      "content": {
+        "elementType": "ThemeProvider",
+        "semanticType": "ThemeProvider",
+        "attrs": {
+          "theme": {
+            "type": "import",
+            "content": {
+              "id": "defaultTheme"
+            }
+          }
+        },
+        "dependency": {
+          "type": "package",
+          "path": "@chakra-ui/core",
+          "version": "0.8.0",
+          "meta": {
+            "namedImport": true
+          }
+        },
+        "children": [
+          {
+            "type": "element",
+            "content": {
+              "elementType": "component",
+              "semanticType": "Button",
+              "attrs": {
+                "variantColor": "teal"
+              },
+              "dependency": {
+                "type": "package",
+                "path": "@chakra-ui/core",
+                "version": "0.8.0",
+                "meta": {
+                  "namedImport": true
+                }
+              },
+              "children": ["Some button"]
+            }
+          }
+        ]
+      }
+    }
+  }
\ No newline at end of file
diff --git a/packages/teleport-component-generator-react/__tests__/integration/component-with-smilar-element-name-depependencies.json b/packages/teleport-component-generator-react/__tests__/integration/component-with-smilar-element-name-depependencies.json
new file mode 100644
index 00000000..6c098ae3
--- /dev/null
+++ b/packages/teleport-component-generator-react/__tests__/integration/component-with-smilar-element-name-depependencies.json
@@ -0,0 +1,117 @@
+{
+    "name": "App",
+    "importDefinitions": {
+      "tokens": {
+        "type": "package",
+        "path": "react-ui",
+        "version": "1.0.0-beta.26",
+        "meta": {
+          "namedImport": true
+        }
+      },
+      "components": {
+        "path": "react-ui",
+        "type": "package",
+        "version": "1.0.0-beta.26",
+        "meta": {
+          "namedImport": true
+        }
+      },
+      "antdCSS": {
+        "path": "antd/dist/antd.css",
+        "type": "package",
+        "version": "4.5.1",
+        "meta": {
+          "importJustPath": true
+        }
+      }
+    },
+    "node": {
+      "type": "element",
+      "content": {
+        "semanticType": "ThemeProvider",
+        "elementType": "component",
+        "attrs": {
+          "tokens": {
+            "type": "import",
+            "content": {
+              "id": "tokens"
+            }
+          },
+          "components": {
+            "type": "import",
+            "content": {
+              "id": "components"
+            }
+          }
+        },
+        "dependency": {
+          "type": "package",
+          "path": "react-ui",
+          "version": "1.0.0-beta.26",
+          "meta": {
+            "namedImport": true
+          }
+        },
+        "children": [
+          {
+            "type": "element",
+            "content": {
+              "semanticType": "Button",
+              "elementType": "component",
+              "attrs": {
+                "variant": "primary"
+              },
+              "children": ["Button from Chakra"],
+              "dependency": {
+                "type": "package",
+                "path": "react-ui",
+                "version": "1.0.0-beta.26",
+                "meta": {
+                  "namedImport": true
+                }
+              }
+            }
+          },
+          {
+            "type": "element",
+            "content": {
+              "semanticType": "Avatar",
+              "elementType": "component",
+              "attrs": {
+                "size": "xlarge",
+                "src": "https://github.com/sameen-shi.png"
+              },
+              "dependency": {
+                "type": "package",
+                "path": "react-ui",
+                "version": "1.0.0-beta.26",
+                "meta": {
+                  "namedImport": true
+                }
+              }
+            }
+          },
+          {
+            "type": "element",
+            "content": {
+              "semanticType": "Button",
+              "elementType": "component",
+              "attrs": {
+                "type": "primary"
+              },
+              "children": ["Button from ANTD"],
+              "dependency": {
+                "type": "package",
+                "path": "antd",
+                "version": "0.8.0",
+                "meta": {
+                  "namedImport": true
+                }
+              }
+            }
+          }
+        ]
+      }
+    }
+  }
\ No newline at end of file
diff --git a/packages/teleport-component-generator-vue/__tests__/integration/component-dependency.ts b/packages/teleport-component-generator-vue/__tests__/integration/component-dependency.ts
index 3aef16a3..41de8dd5 100644
--- a/packages/teleport-component-generator-vue/__tests__/integration/component-dependency.ts
+++ b/packages/teleport-component-generator-vue/__tests__/integration/component-dependency.ts
@@ -4,6 +4,7 @@ import {
   elementNode,
   componentDependency,
 } from '@teleporthq/teleport-uidl-builders'
+import componentJSON from './component-with-smilar-element-name-depependencies.json'
 
 import { createVueComponentGenerator } from '../../src'
 
@@ -35,6 +36,20 @@ const uidl = (dependency) => {
 
 describe('Component with dependency ', () => {
   describe('from package.json', () => {
+    it('Remaps elementName when to elements have same name but different dependencies', async () => {
+      const result = await vueGenerator.generateComponent(componentJSON)
+      const vueFile = result.files[0]
+
+      expect(vueFile).toBeDefined()
+      expect(vueFile.content).toContain(
+        `import { CThemeProvider, CButton, CAvatar } from '@chakra-ui/vue'`
+      )
+      expect(vueFile.content).toContain(`import { CButton as AntdCButton } from 'antd'`)
+      expect(vueFile.content).toContain(`import 'antd/dist/antd.css'`)
+      expect(vueFile.content).toContain(`randomName: randomName`)
+      expect(vueFile.content).not.toContain(`antdCSS: antdCSS`)
+    })
+
     it('renders code with imported package', async () => {
       const result = await vueGenerator.generateComponent(
         uidl(
diff --git a/packages/teleport-component-generator-vue/__tests__/integration/component-with-smilar-element-name-depependencies.json b/packages/teleport-component-generator-vue/__tests__/integration/component-with-smilar-element-name-depependencies.json
new file mode 100644
index 00000000..a5caff16
--- /dev/null
+++ b/packages/teleport-component-generator-vue/__tests__/integration/component-with-smilar-element-name-depependencies.json
@@ -0,0 +1,100 @@
+{
+  "name": "App",
+  "importDefinitions": {
+    "randomName": {
+      "type": "package",
+      "path": "some-random-name-exporting-package",
+      "version": "0.0.1",
+      "meta": {
+        "namedImport": true
+      }
+    },
+    "antdCSS": {
+      "type": "package",
+      "path": "antd/dist/antd.css",
+      "version": "0.8.0",
+      "meta": {
+        "importJustPath": true
+      }
+    }
+  },
+  "node": {
+    "type": "element",
+    "content": {
+      "semanticType": "CThemeProvider",
+      "elementType": "component",
+      "dependency": {
+        "type": "package",
+        "path": "@chakra-ui/vue",
+        "version": "0.6.1",
+        "meta": {
+          "namedImport": true
+        }
+      },
+      "children": [
+        {
+          "type": "element",
+          "content": {
+            "semanticType": "CButton",
+            "elementType": "component",
+            "attrs": {
+              "variant": "primary"
+            },
+            "children": ["Button from Chakra"],
+            "dependency": {
+              "type": "package",
+              "path": "@chakra-ui/vue",
+              "version": "0.6.1",
+              "meta": {
+                "namedImport": true
+              }
+            }
+          }
+        },
+        {
+          "type": "element",
+          "content": {
+            "semanticType": "CAvatar",
+            "elementType": "component",
+            "attrs": {
+              "name": {
+                "type": "import",
+                "content": {
+                  "id": "randomName"
+                }
+              },
+              "src": "https://github.com/sameen-shi.png"
+            },
+            "dependency": {
+              "type": "package",
+              "path": "@chakra-ui/vue",
+              "version": "0.6.1",
+              "meta": {
+                "namedImport": true
+              }
+            }
+          }
+        },
+        {
+          "type": "element",
+          "content": {
+            "semanticType": "CButton",
+            "elementType": "component",
+            "attrs": {
+              "type": "primary"
+            },
+            "children": ["Button from ANTD"],
+            "dependency": {
+              "type": "package",
+              "path": "antd",
+              "version": "0.8.0",
+              "meta": {
+                "namedImport": true
+              }
+            }
+          }
+        }
+      ]
+    }
+  }
+}
\ No newline at end of file
diff --git a/packages/teleport-project-generator-next/__tests__/end2end/index.ts b/packages/teleport-project-generator-next/__tests__/end2end/index.ts
index 8faed374..6a5c5ea3 100644
--- a/packages/teleport-project-generator-next/__tests__/end2end/index.ts
+++ b/packages/teleport-project-generator-next/__tests__/end2end/index.ts
@@ -3,12 +3,32 @@ import uidlSample from '../../../../examples/test-samples/project-sample.json'
 // @ts-ignore
 import invalidUidlSample from '../../../../examples/test-samples/project-invalid-sample.json'
 // @ts-ignore
+import uidlSampleWithoutProjectStyleesButImports from './project-with-import-without-global-styles.json'
+// @ts-ignore
 import template from './template-definition.json'
 import { createNextProjectGenerator } from '../../src'
 
 describe('React Next Project Generator', () => {
   const generator = createNextProjectGenerator()
 
+  it('runs without crashing and adding external imports to _app.js', async () => {
+    const outputFolder = await generator.generateProject(
+      uidlSampleWithoutProjectStyleesButImports,
+      template
+    )
+    const assetsPath = generator.getAssetsPath()
+
+    const publicFolder = outputFolder.subFolders.find((folder) => folder.name === 'pages')
+    const appFile = publicFolder.files.find((file) => file.name === '_app')
+
+    expect(assetsPath).toBeDefined()
+    expect(outputFolder.name).toBe(template.name)
+    expect(outputFolder.files[0].name).toBe('package')
+    expect(appFile).toBeDefined()
+    expect(appFile.content).toContain(`import "antd/dist/antd.css`)
+    expect(appFile.content).not.toContain(`import './style.css'`)
+  })
+
   it('runs without crashing', async () => {
     const outputFolder = await generator.generateProject(uidlSample, template)
     const assetsPath = generator.getAssetsPath()
diff --git a/packages/teleport-project-generator-next/__tests__/end2end/project-with-import-without-global-styles.json b/packages/teleport-project-generator-next/__tests__/end2end/project-with-import-without-global-styles.json
new file mode 100644
index 00000000..4c9a2073
--- /dev/null
+++ b/packages/teleport-project-generator-next/__tests__/end2end/project-with-import-without-global-styles.json
@@ -0,0 +1,583 @@
+{
+    "name": "myVueProject",
+    "globals": {
+      "settings": {
+        "language": "en",
+        "title": "teleportHQ"
+      },
+      "meta" : [
+        { "name": "description", "content": "Free Web tutorials" },
+        { "name": "keywords", "content": "prea bun, prea ca la tara" },
+        { "name": "viewport", "content": "width=device-width, initial-scale=1.0" },
+        { "property": "og:title", "content": "Free Web tutorials" },
+        { "property": "og:url", "content": "/playground_assets/asdasd.png" }
+      ],
+      "manifest": {
+        "icons": [
+          {
+            "src": "/playground_assets/icons-192.png",
+            "type": "image/png",
+            "sizes": "192x192"
+          },
+          {
+            "src": "/playground_assets/icons-512.png",
+            "type": "image/png",
+            "sizes": "512x512"
+          }
+        ],
+        "theme_color": "#822CEC",
+        "background_color": "#822CEC"
+      },
+      "assets": [
+        {
+          "type": "style",
+          "path": "https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.1/normalize.min.css",
+          "options": {
+            "target": "body"
+          }
+        }, 
+        {
+          "type": "script",
+          "path": "https://www.googletagmanager.com/gtm.js",
+          "options": {
+            "defer": true
+          }
+        },
+        {
+          "type": "script",
+          "content": "console.log(\"inline script\")",
+          "options": {
+            "target": "body"
+          }
+        },
+        {
+          "type": "font",
+          "path": "https://fonts.googleapis.com/css?family=Roboto"
+        },
+        {
+          "type": "style",
+          "content": "body{font-family: 'Roboto', sans-serif;}"
+        },
+        {
+          "type": "icon",
+          "path": "/playground_assets/favicon-32x32.png",
+          "options": {
+            "iconType": "image/png",
+            "iconSizes": "32x32"
+          }
+        }
+      ],
+      "variables": {
+        "primaryColor": "#822CEC",
+        "secondaryColor": "#414141",
+        "spacing": "10px"
+      }
+    },
+    "root": {
+      "name": "App",
+      "importDefinitions": {
+        "antdCSS": {
+            "type": "package",
+            "path": "antd/dist/antd.css",
+            "version": "^4.5.1",
+            "meta": {
+              "importJustPath": true
+            }
+          }
+      },
+      "stateDefinitions": {
+        "route": {
+          "type": "string",
+          "defaultValue": "index",
+          "values": [
+            {
+              "value": "index",
+              "pageOptions": {
+                "navLink": "/",
+                "fileName": "index",
+                "componentName": "Home"
+              }
+            },
+            {
+              "value": "about",
+              "pageOptions": {
+                "navLink": "/about",
+                "fileName": "about",
+                "componentName": "About"
+              }
+            },
+            {
+              "value": "contact-us",
+              "pageOptions": {
+                "navLink": "/here-we-are",
+                "fileName": "contact-us",
+                "componentName": "Us"
+              }
+            }
+          ]
+        }
+      },
+      "node": {
+        "type": "element",
+        "content": {
+          "elementType": "Router",
+          "children": [
+            {
+              "type": "conditional",
+              "content": {
+                "node": {
+                  "type": "element",
+                  "content": {
+                    "elementType": "container",
+                    "children": [
+                      {
+                        "type": "static",
+                        "content": "Page 1"
+                      }
+                    ]
+                  }
+                },
+                "value": "index",
+                "reference": {
+                  "type": "dynamic",
+                  "content": {
+                    "referenceType": "state",
+                    "id": "route"
+                  }
+                }
+              }
+            },
+            {
+              "type": "conditional",
+              "content": {
+                "node": {
+                  "type": "element",
+                  "content": {
+                    "elementType": "container",
+                    "children": [
+                      {
+                        "type": "static",
+                        "content": "Page 2"
+                      }
+                    ]
+                  }
+                },
+                "value": "about",
+                "reference": {
+                  "type": "dynamic",
+                  "content": {
+                    "referenceType": "state",
+                    "id": "route"
+                  }
+                }
+              }
+            },{
+              "type": "conditional",
+              "content": {
+                "node": {
+                  "type": "element",
+                  "content": {
+                    "elementType": "container",
+                    "children": [
+                      {
+                        "type": "static",
+                        "content": "Page 3"
+                      }
+                    ]
+                  }
+                },
+                "value": "contact-us",
+                "reference": {
+                  "type": "dynamic",
+                  "content": {
+                    "referenceType": "state",
+                    "id": "route"
+                  }
+                }
+              }
+            }
+          ]
+        }
+      }
+    },
+    "components": {
+      "OneComponent": {
+        "name": "OneComponent",
+        "propDefinitions": {
+          "titleValue": {
+            "type": "string",
+            "defaultValue": "Hello"
+          },
+          "items": {
+            "type": "array",
+            "defaultValue": []
+          }
+        },
+        "stateDefinitions": {
+          "isVisible": {
+            "type": "boolean",
+            "defaultValue": true
+          }
+        },
+        "node": {
+          "type": "element",
+          "content": {
+            "elementType": "container",
+            "attrs": {
+              "data-static-attr": {
+                "type": "static",
+                "content": "test"
+              },
+              "data-dynamic-attr": {
+                "type": "dynamic",
+                "content": {
+                  "referenceType": "prop",
+                  "id": "titleValue"
+                }
+              }
+            },
+            "children": [
+                {
+                    "type": "element",
+                    "content": {
+                      "semanticType": "Button",
+                      "elementType": "component",
+                      "attrs": {
+                        "type": "danger"
+                      },
+                      "dependency": {
+                        "type": "package",
+                        "version": "^4.5.1",
+                        "path": "antd",
+                        "meta": {
+                          "namedImport": true
+                        }
+                      },
+                      "children": ["Button from Antd"]
+                    }
+                  },
+              {
+                "type": "element",
+                "content": {
+                  "elementType": "text",
+                  "children": [
+                    {
+                      "type": "static",
+                      "content": "Hello World!"
+                    },
+                    {
+                      "type": "dynamic",
+                      "content": {
+                        "referenceType": "prop",
+                        "id": "titleValue"
+                      }
+                    }
+                  ]
+                }
+              },
+              {
+                "type": "repeat",
+                "content": {
+                  "node": {
+                    "type": "element",
+                    "content": {
+                      "elementType": "text",
+                      "children": [
+                        {
+                          "type": "dynamic",
+                          "content": {
+                            "referenceType": "local",
+                            "id": "item"
+                          }
+                        },
+                        {
+                          "type": "element",
+                          "content": {
+                            "elementType": "list",
+                            "attrs": {
+                              "items": {
+                                "type": "static",
+                                "content": ["angular", "react", "vue"]
+                              }
+                            }
+                          }
+                        }
+                      ]
+                    }
+                  },
+                  "dataSource": {
+                    "type": "dynamic",
+                    "content": {
+                      "referenceType": "prop",
+                      "id": "items"
+                    }
+                  },
+                  "meta": {
+                    "useIndex": true,
+                    "iteratorName": "item"
+                  }
+                }
+              },
+              {
+                "type": "conditional",
+                "content": {
+                  "reference": {
+                    "type": "dynamic",
+                    "content": {
+                      "referenceType": "state",
+                      "id": "isVisible"
+                    }
+                  },
+                  "value": true,
+                  "node": {
+                    "type": "element",
+                    "content": {
+                      "elementType": "text",
+                      "children": [{
+                        "type": "static",
+                        "content": "Now you see me!"
+                      }]
+                    }
+                  }
+                }
+              }
+            ]
+          }
+        }
+      },
+      "ExpandableArea": {
+        "name": "ExpandableArea",
+        "propDefinitions": {
+          "titleValue": {
+            "type": "string",
+            "defaultValue": "Hello"
+          },
+          "text": {
+            "type": "string",
+            "defaultValue": "Is it me you're looking for?"
+          }
+        },
+        "stateDefinitions": {
+          "isExpanded": {
+            "type": "boolean",
+            "defaultValue": false
+          }
+        },
+        "node": {
+          "type": "element",
+          "content": {
+            "elementType": "container",
+            "style": {
+              "margin": "10px"
+            },
+            "children": [
+              {
+                "type": "element",
+                "content": {
+                  "elementType": "text",
+                  "children": [{
+                    "type": "dynamic",
+                    "content": {
+                      "referenceType": "prop",
+                      "id": "titleValue"
+                    }
+                  }]
+                }
+              },
+              {
+                "type": "element",
+                "content": {
+                  "elementType": "button",
+                  "children": [{
+                    "type": "conditional",
+                    "content": {
+                      "node": {
+                        "type": "static",
+                        "content": "Hide me"
+                      },
+                      "value": true,
+                      "reference": {
+                        "type": "dynamic",
+                        "content": {
+                          "referenceType": "state",
+                          "id": "isExpanded"
+                        }
+                      }
+                    }
+                  },{
+                    "type": "conditional",
+                    "content": {
+                      "node": {
+                        "type": "static",
+                        "content": "Show me"
+                      },
+                      "value": false,
+                      "reference": {
+                        "type": "dynamic",
+                        "content": {
+                          "referenceType": "state",
+                          "id": "isExpanded"
+                        }
+                      }
+                    }
+                  }],
+                  "events": {
+                    "click": [
+                      {
+                        "type": "stateChange",
+                        "modifies": "isExpanded",
+                        "newState": "$toggle"
+                      }
+                    ]
+                  }
+                }
+              },
+              {
+                "type": "conditional",
+                "content": {
+                  "node": {
+                    "type": "element",
+                    "content": {
+                      "elementType": "text",
+                      "children": [{
+                        "type": "dynamic",
+                        "content": {
+                          "referenceType": "prop",
+                          "id": "text"
+                        }
+                      }]
+                    }
+                  },
+                  "value": true,
+                  "reference": {
+                    "type": "dynamic",
+                    "content": {
+                      "referenceType": "state",
+                      "id": "isExpanded"
+                    }
+                  }
+                }
+              }
+            ]
+          }
+        }
+      },
+      "Modal": {
+        "name": "Modal",
+        "stateDefinitions": {
+          "isOpen": {
+            "type": "boolean",
+            "defaultValue": false
+          }
+        },
+        "node": {
+          "type": "element",
+          "content": {
+            "elementType": "group",
+            "children": [
+              {
+                "type": "element",
+                "content": {
+                  "elementType": "button",
+                  "name": "openmodal",
+                  "children": [{
+                    "type": "static",
+                    "content": "Show Popup"
+                  }],
+                  "events": {
+                    "click": [{
+                      "type": "stateChange",
+                      "modifies": "isOpen",
+                      "newState": true
+                    }]
+                  }
+                }
+              },
+              {
+                "type": "conditional",
+                "content": {
+                  "node": {
+                    "type": "element",
+                    "content": {
+                      "elementType": "ModalWindow",
+                      "name": "window",
+                      "dependency": {
+                        "type": "local"
+                      },
+                      "events": {
+                        "onClose": [{
+                          "type": "stateChange",
+                          "modifies": "isOpen",
+                          "newState": false
+                        }]
+                      }
+                    }
+                  },
+                  "value": true,
+                  "reference": {
+                    "type": "dynamic",
+                    "content": {
+                      "referenceType": "state",
+                      "id": "isOpen"
+                    }
+                  }
+                }
+              }
+            ]
+          }
+        }
+      },
+      "ModalWindow": {
+        "name": "ModalWindow",
+        "propDefinitions": {
+          "message": {
+            "type": "string",
+            "defaultValue": "Hello"
+          },
+          "onClose": {
+            "type": "func",
+            "defaultValue": "() => {}"
+          }
+        },
+        "stateDefinitions": {
+          "fakeState": {
+            "type": "boolean",
+            "defaultValue": false
+          }
+        },
+        "node": {
+          "type": "element",
+          "content": {
+            "elementType": "container",
+            "children": [{
+              "type": "dynamic",
+              "content": {
+                "referenceType": "prop",
+                "id": "message"
+              }
+            },{
+              "type": "element",
+              "content": {
+                "elementType": "button",
+                "name": "close",
+                "children": [{
+                  "type": "static",
+                  "content": "Close me"
+                }],
+                "events": {
+                  "click": [{
+                    "type": "propCall",
+                    "calls": "onClose"
+                  },{
+                    "type": "stateChange",
+                    "modifies": "fakeState",
+                    "newState": false
+                  }]
+                }
+              }
+            }]
+          }
+        }
+      }
+    }
+  }
\ No newline at end of file
diff --git a/packages/teleport-project-generator/__tests__/utils.ts b/packages/teleport-project-generator/__tests__/utils.ts
index c28a476f..bb140581 100644
--- a/packages/teleport-project-generator/__tests__/utils.ts
+++ b/packages/teleport-project-generator/__tests__/utils.ts
@@ -174,38 +174,38 @@ describe('extractPageOptions', () => {
   }
 
   it('uses the state for a non-declared page', () => {
-    const result = extractPageOptions(routeDefinitions, 'non-declared')
-    expect(result.navLink).toBe('/non-declared')
-    expect(result.fileName).toBe('non-declared')
-    expect(result.componentName).toBe('NonDeclared')
+    const { pageOptions } = extractPageOptions(routeDefinitions, 'non-declared')
+    expect(pageOptions.navLink).toBe('/non-declared')
+    expect(pageOptions.fileName).toBe('non-declared')
+    expect(pageOptions.componentName).toBe('NonDeclared')
   })
 
   it('uses the state for a page without meta', () => {
-    const result = extractPageOptions(routeDefinitions, 'no-meta')
-    expect(result.navLink).toBe('/no-meta')
-    expect(result.fileName).toBe('no-meta')
-    expect(result.componentName).toBe('NoMeta')
+    const { pageOptions } = extractPageOptions(routeDefinitions, 'no-meta')
+    expect(pageOptions.navLink).toBe('/no-meta')
+    expect(pageOptions.fileName).toBe('no-meta')
+    expect(pageOptions.componentName).toBe('NoMeta')
   })
 
   it('returns values from the meta with defaults from the state', () => {
-    const result = extractPageOptions(routeDefinitions, 'about')
-    expect(result.navLink).toBe('/about-us') // meta value
-    expect(result.fileName).toBe('about') // state value
-    expect(result.componentName).toBe('AboutUs') // meta value
+    const { pageOptions } = extractPageOptions(routeDefinitions, 'about')
+    expect(pageOptions.navLink).toBe('/about-us') // meta value
+    expect(pageOptions.fileName).toBe('about') // state value
+    expect(pageOptions.componentName).toBe('AboutUs') // meta value
   })
 
   it('converts the fileName to index', () => {
-    const result = extractPageOptions(routeDefinitions, 'home', true)
-    expect(result.navLink).toBe('/')
-    expect(result.fileName).toBe('index')
-    expect(result.componentName).toBe('Home')
+    const { pageOptions } = extractPageOptions(routeDefinitions, 'home', true)
+    expect(pageOptions.navLink).toBe('/')
+    expect(pageOptions.fileName).toBe('index')
+    expect(pageOptions.componentName).toBe('Home')
   })
 
   it('uses the path as the fileName', () => {
-    const result = extractPageOptions(routeDefinitions, 'about', true)
-    expect(result.navLink).toBe('/about-us')
-    expect(result.fileName).toBe('about-us')
-    expect(result.componentName).toBe('AboutUs')
+    const { pageOptions } = extractPageOptions(routeDefinitions, 'about', true)
+    expect(pageOptions.navLink).toBe('/about-us')
+    expect(pageOptions.fileName).toBe('about-us')
+    expect(pageOptions.componentName).toBe('AboutUs')
   })
 })
 
diff --git a/packages/teleport-shared/__tests__/utils/uidl-utils.ts b/packages/teleport-shared/__tests__/utils/uidl-utils.ts
index 825cbea8..972df9fa 100644
--- a/packages/teleport-shared/__tests__/utils/uidl-utils.ts
+++ b/packages/teleport-shared/__tests__/utils/uidl-utils.ts
@@ -15,6 +15,7 @@ import {
   traverseNodes,
   traverseElements,
   traverseRepeats,
+  extractExternalDependencies,
 } from '../../src/utils/uidl-utils'
 import {
   component,
@@ -34,11 +35,35 @@ import {
   UIDLSlotNode,
   UIDLAttributeValue,
   ComponentUIDL,
+  UIDLDependency,
 } from '@teleporthq/teleport-types'
 
 import uidlStyleJSON from './uidl-utils-style.json'
 import projectUIDL from '../../../../examples/test-samples/project-sample.json'
 
+describe('Assembly Line', () => {
+  it('extract external dependencies', () => {
+    const dependencies: Record<string, UIDLDependency> = {
+      react: {
+        type: 'library',
+        path: 'react',
+        version: '16.8.0',
+      },
+      antd: {
+        type: 'package',
+        path: 'antd',
+        version: '4.5.1',
+        meta: {
+          namedImport: true,
+        },
+      },
+    }
+    const result = extractExternalDependencies(dependencies)
+
+    expect(Object.keys(result).length).toBe(1)
+  })
+})
+
 describe('cleanupDynamicStyles', () => {
   const styleObject = uidlStyleJSON as UIDLStyleDefinitions
 
diff --git a/packages/teleport-test/src/standalone.ts b/packages/teleport-test/src/standalone.ts
index 428c6553..d6fae01f 100644
--- a/packages/teleport-test/src/standalone.ts
+++ b/packages/teleport-test/src/standalone.ts
@@ -1,11 +1,13 @@
-import { readFileSync } from 'fs'
+import { readFileSync, rmdirSync, mkdirSync } from 'fs'
 import { join } from 'path'
 import { packProject } from '@teleporthq/teleport-code-generator'
 import { ProjectUIDL, PackerOptions, ProjectType, PublisherType } from '@teleporthq/teleport-types'
 
+import reactProjectJSON from '../../../examples/uidl-samples/react-project.json'
 import projectJSON from '../../../examples/uidl-samples/project.json'
 
 const projectUIDL = (projectJSON as unknown) as ProjectUIDL
+const reactProjectUIDL = (reactProjectJSON as unknown) as ProjectUIDL
 const assetFile = readFileSync(join(__dirname, 'asset.png'))
 const base64File = new Buffer(assetFile).toString('base64')
 const packerOptions: PackerOptions = {
@@ -30,29 +32,49 @@ const packerOptions: PackerOptions = {
 
 const run = async () => {
   try {
+    if (packerOptions.publisher === PublisherType.DISK) {
+      rmdirSync('dist', { recursive: true })
+      mkdirSync('dist')
+    }
+
     let result
     // result = await packProject(projectUIDL, {
     //   ...packerOptions,
     //   projectType: ProjectType.REACTNATIVE,
     // })
     // console.info(ProjectType.REACTNATIVE, '-', result.payload)
-    result = await packProject(projectUIDL, { ...packerOptions, projectType: ProjectType.REACT })
+    result = await packProject(reactProjectUIDL, {
+      ...packerOptions,
+      projectType: ProjectType.REACT,
+    })
     console.info(ProjectType.REACT, '-', result.payload)
-    result = await packProject(projectUIDL, { ...packerOptions, projectType: ProjectType.NEXT })
+    result = await packProject(reactProjectUIDL, {
+      ...packerOptions,
+      projectType: ProjectType.NEXT,
+    })
     console.info(ProjectType.NEXT, '-', result.payload)
     result = await packProject(projectUIDL, { ...packerOptions, projectType: ProjectType.NUXT })
     console.info(ProjectType.NUXT, '-', result.payload)
-    result = await packProject(projectUIDL, { ...packerOptions, projectType: ProjectType.VUE })
+    result = await packProject(reactProjectUIDL, { ...packerOptions, projectType: ProjectType.VUE })
     console.info(ProjectType.VUE, '-', result.payload)
     result = await packProject(projectUIDL, { ...packerOptions, projectType: ProjectType.STENCIL })
     console.info(ProjectType.STENCIL, '-', result.payload)
-    result = await packProject(projectUIDL, { ...packerOptions, projectType: ProjectType.PREACT })
+    result = await packProject(reactProjectUIDL, {
+      ...packerOptions,
+      projectType: ProjectType.PREACT,
+    })
     console.info(ProjectType.PREACT, '-', result.payload)
-    result = await packProject(projectUIDL, { ...packerOptions, projectType: ProjectType.ANGULAR })
+    result = await packProject(projectUIDL, {
+      ...packerOptions,
+      projectType: ProjectType.ANGULAR,
+    })
     console.info(ProjectType.ANGULAR, '-', result.payload)
     result = await packProject(projectUIDL, { ...packerOptions, projectType: ProjectType.GRIDSOME })
     console.info(ProjectType.GRIDSOME, '-', result.payload)
-    result = await packProject(projectUIDL, { ...packerOptions, projectType: ProjectType.GATSBY })
+    result = await packProject(reactProjectUIDL, {
+      ...packerOptions,
+      projectType: ProjectType.GATSBY,
+    })
     console.info(ProjectType.GATSBY, '-', result.payload)
   } catch (e) {
     console.info(e)