Angular 2 пакет как импорт/импорт нескольких модулей
Я не знал, как сформулировать вопрос...
Итак, в основном я пишу свое приложение, используя Angular 2 с Typescript. Я хотел бы сделать возможным импортировать модули так, как мы делаем с Angular, где мы можем импортировать несколько связанных модулей в одну строку.
Например, мы могли бы сделать это в angular2 beta:
import { Component, OnInit, Input } from 'angular2/core';
Я хотел бы сделать что-то подобное с моим приложением. Например:
import { UserService, RoleService } from 'my-project/services';
Кроме того, я хочу иметь возможность делать то же самое для моделей, труб, компонентов и т.д.
Еще одна вещь: структура папок будет примерно такой:
SRC/приложения/услуги
SRC/приложения/компоненты
SRC/приложение/модели
src/app/pipes
Что я пытался сделать:
На пути src/app я создал файл для каждого "пакета", например services.d.ts, models.d.ts, pipes.d.ts...
И затем я попытался отобразить конфигурацию SystemJS, например:
(function(global) {
// map tells the System loader where to look for things
var map = {
'app': 'src/app', // 'dist',
'rxjs': 'node_modules/rxjs',
'my-project/components': 'src/app/components',
'my-project/services': 'src/app/services',
'my-project/models': 'src/app/models',
'my-project/pipes': 'src/app/pipes',
'@angular': 'node_modules/@angular'
};
// packages tells the System loader how to load when no filename and/or no extension
var packages = {
'app': { format: 'register', main: 'main.js', defaultExtension: 'js' },
'rxjs': { defaultExtension: 'js' },
};
var packageNames = [
'my-project/components',
'my-project/services',
'my-project/models',
'my-project/pipes',
'@angular/common',
'@angular/compiler',
'@angular/core',
'@angular/http',
'@angular/platform-browser',
'@angular/platform-browser-dynamic',
'@angular/router-deprecated',
'@angular/testing',
'@angular/upgrade',
];
// add package entries for angular packages in the form '@angular/common': { main: 'index.js', defaultExtension: 'js' }
packageNames.forEach(function(pkgName) {
packages[pkgName] = { main: 'index.js', defaultExtension: 'js' };
});
var config = {
map: map,
packages: packages
};
System.config(config);
})(this);
Проблема заключается в том, что Visual Studio Code не распознает импорт в моих .ts файлах. Он говорит, что не может найти модуль.
Ответы
Ответ 1
Вам нужно 2 вещи для достижения этого. Во-первых, как указывал другой ответ, вам нужно создать "баррелей" (index.ts
) внутри src/app/services
, src/app/models
и других таких папок. Таким образом, структура папок выглядит примерно так:
![введите описание изображения здесь]()
Если файлы index.ts
содержат экспорт материалов, которые вы хотите импортировать в приложение:
export * from './service1';
export * from './service2';
До сих пор это даст вам возможность сделать это:
import { Service1, Service2 } from '../../services';
Однако это не является идеальным из-за относительных путей, таких как ../../
. Чтобы исправить это, вам нужно сделать еще один шаг: укажите baseUrl
и paths
TypeScript параметры в tsconfig.json
(см. https://www.typescriptlang.org/docs/handbook/module-resolution.html).
Если вы хотите избавиться только от относительных путей, вам просто нужно указать параметр baseUrl
следующим образом:
tsconfig.json:
{
"compilerOptions": {
...
"baseUrl": "./src"
}
}
После этого вы сможете импортировать свои службы следующим образом:
import { Service1, Service2 } from 'app/services';
Но если вам нужно также импортировать как my-project/services
(my-project
вместо app
), вам также нужно указать конфигурацию paths
следующим образом:
{
"compilerOptions": {
...
"baseUrl": "./src",
"paths": {
"my-project/*": [
"app/*"
]
}
}
}
При такой конфигурации должно работать следующее:
import { Service1, Service2 } from 'my-project/services';
Ответ 2
Вы хотите создать баррель внутри папки services
(например), который будет экспортировать все вложенные экспорт вручную, таким образом вы можете импортировать 2 (или более) модуля из ствола, где перед тем, как вы будете иметь использовать 2 разных импорта.
Последнее, что я слышал, это по какой-то причине ломает дерево, но я могу ошибаться.
В любом случае, прочитайте еще здесь.
Ответ 3
Изменить: ближе к тому, что вы хотите
Вы можете сгенерировать файлы объявления вашего приложения и добавить их в папку @types (или создать свой собственный и добавить это в массив tsconfig typeRoots
).
Новый tsconfig
Вы можете использовать консоль, но я бы рекомендовал создать новый файл tsconfig_decl.json
. К сожалению, я не нашел способ просто создавать объявления, поэтому вам нужно очистить папку dist
.
Пример tsconfig_decl.json
Важными свойствами являются declaration
, declarationDir
, и я думаю, outDir
знать, какую папку удалить.
{
"compilerOptions": {
"baseUrl": "",
"declaration": true,
"declarationDir": "../node_modules/@types/myproject",
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"lib": ["es6", "dom"],
"mapRoot": "./",
"module": "es6",
"moduleResolution": "node",
"outDir": "../dist/dec-del",
"sourceMap": true,
"target": "es5",
"typeRoots": [
"../node_modules/@types"
]
}
}
Создание объявлений
tsc -p "src/tsconfig_decl.json"
Если структура папок/бочки верны, вы должны иметь возможность использовать
import { AuthService, UserService } from 'myproject/services';
--------------- Старый ответ ---------------
Если у вас есть эта структура
SRC/приложения/услуги
SRC/приложения/компоненты
SRC/приложение/модели
SRC/приложение/трубы
вы можете создать index.ts
файлы (баррелей) внутри этих папок, которые экспортируют все доступные сервисы/компоненты/.... Затем вы можете получить к ним доступ, используя app/services
. Это не совсем то, что вы хотите, но вы можете переименовать папку приложения, чтобы получить название проекта там, или я думаю, что изменение процесса сборки может помочь с этим.
ЦСИ/приложение/услуги/index.ts
export * from './auth.service';
export * from './user.service';
...
Использование служб
import { AuthService, UserService } from 'app/services';
...
Если у вас есть более глубокая структура, вам нужно создать бочки в цепочке или использовать относительный путь на верхнем уровне, чтобы получить желаемый путь.