我目前正在使用TypeScript和Angular2开发一个Electron应用程序,为此我创建了许多不同的类,所有这些都在不同的文件中。为了使我的应用程序的重构更容易,我希望在导入这些类时不必使用相对路径。
现在,要导入它们,我使用以下语法:import {Trigger} from './../../trigger/ts/trigger.component';
我想要做的是使用如下所示的语法:import {Trigger} from 'trigger.component';
那可能吗?
答案 0 :(得分:3)
您可以创建一个文件,例如:components.ts,并在该组件中引用所有组件,例如:
export {Trigger} from '../trigger/ts/trigger.component'
export {Cmp} from '../cmp/ts/cmp.component'
...
比,当你想加载一个组件时,你可以这样做:
import {Trigger} from '../components.ts'
分组事物是一种很好的做法。
答案 1 :(得分:2)
我使用ScriptCS创建了一个导出器来做到这一点。我是用C#写的,但是欢迎你用你喜欢的任何语言重写它。
它允许您在每个组件目录的根目录中有一个导出文件,您可以通过执行以下操作导入该文件:
import {LoginPage, HomePage} from '../pages/export'
或
import {NavBarComponent, HeroCardComponent} from '../controls/export'
假设您在特定目录中有多个组件,例如:
如果您运行scriptcs exporter.cs -- app/pages app/controls
它将在每个指定的目录中生成一个名为export.ts
的输出文件,其中包含目录中包含的每个类的导出语句(通过递归迭代)
<强> exporter.cs 强>
// USAGE
// scriptcs exporter.cs -- app/Templates app/Controls
using System.Text.RegularExpressions;
CreateExports();
public void CreateExports() {
// e.g. 'C:\Apps\MyProject'
string rootDir = new DirectoryInfo(@".\").FullName;
string exportFileName = "export.ts";
List<string> exportDirectoryPaths = new List<string>();
foreach (string argument in Env.ScriptArgs) {
if (argument.Contains(".ts"))
exportFileName = argument;
else
exportDirectoryPaths.Add(argument);
}
Console.WriteLine("File Name:" + exportFileName);
foreach (string exportDirPath in exportDirectoryPaths) {
// e.g. 'app\Templates'
var exportDirPathFixed = exportDirPath.Replace("/", "\\");
Console.WriteLine(String.Format("Exporting -> {0}", exportDirPath));
List<ExportEntry> exportEntriesToWrite = new List<ExportEntry>();
// e.g. 'C:\Apps\MyProject\app\Templates'
DirectoryInfo exportDir = new DirectoryInfo(rootDir + exportDirPathFixed);
foreach (FileInfo file in exportDir.EnumerateFiles("*.ts", SearchOption.AllDirectories)) {
// Don't export the export file ;)
if (file.Name == exportFileName)
continue;
// e.g. toAdd = {
// RelativepathToExportDirectory = './app/templates/template-one.component'
// ClassName = 'TemplateOneComponent' (Parsed from file contents, works with interfaces)
ExportEntry toAdd = CreateExportEntry(file, exportDirPathFixed, rootDir);
exportEntriesToWrite.Add(toAdd);
}
CreateExportFile(exportDir.FullName + "\\" + exportFileName, exportEntriesToWrite);
}
}
private void CreateExportFile(string exportFilePath, IEnumerable<ExportEntry> exportEntries) {
string textToWrite = "";
foreach (ExportEntry entry in exportEntries) {
textToWrite += entry.ToString() + Environment.NewLine;
}
Console.WriteLine("Text: " + Environment.NewLine + textToWrite);
File.WriteAllText(exportFilePath, textToWrite);
}
// -- Create Export Entry -- //
private ExportEntry CreateExportEntry(FileInfo exportFile, string exportDirPath, string rootDir) {
ExportEntry toReturn = new ExportEntry() {
ClassName = GetFirstExportClassName(exportFile),
RelativepathToExportDirectory = exportFile.FullName.Remove(0, rootDir.Length + exportDirPath.Length).Replace(".ts", ""),
};
return toReturn;
}
private string GetFirstExportClassName(FileInfo exportFile) {
string className = null;
Regex regular = new Regex(@"(?<=export[\s+]class|interface)[^s+][^\s]+");
using (StreamReader streamer = new StreamReader(exportFile.OpenRead())) {
string contents = streamer.ReadToEnd();
Match componentNameMatch = regular.Match(contents);
className = componentNameMatch.ToString().Replace("{", "");
}
return className;
}
public class ExportEntry {
public string RelativepathToExportDirectory { get; set; }
private string _ClassName;
public string ClassName {
get { return _ClassName; }
set { _ClassName = value.Trim(); }
}
/// <summary>
/// Returns the formatted export entry
/// e.g. " export {MyComponents} from './Components/my-component.component' "
/// </summary>
/// <returns></returns>
public override string ToString() {
// export { AppComponent} from './my-template/my-template.component'
return String.Format("export {{ {0} }} from '.{1}';", this.ClassName, this.RelativepathToExportDirectory).Replace('\\', '/');
}
}
答案 2 :(得分:2)
最好在tsconfig.json中使用以下配置
{
"compilerOptions": {
"...": "reduced for brevity",
"baseUrl": "src",
"paths": {
"@app/*": ["app/*"],
"@trigger/*": ["app/trigger/ts/*"]
}
}
}
对于您的情况,使用可以import {Trigger} from '@app/trigger/ts/trigger.component';
或import {Trigger} from '@trigger/trigger.component';
或您可以配置的任何级别的路径。
答案 3 :(得分:0)
实现这一目标的一种简单方法是使用Typescript v2。*的路径,就像在这里使用它一样:https://github.com/MarkPieszak/aspnetcore-angular2-universal
总之,您可以将index.ts文件添加到文件夹,例如
export * from './app.component'
export * from './shared/other.component'
然后让webpack来处理它。 您应该添加到webpack.config.js
const clone = require('js.clone');
const ContextReplacementPlugin = require('webpack/lib/ContextReplacementPlugin');
const TsConfigPathsPlugin = require('awesome-typescript-loader').TsConfigPathsPlugin;
[...]
const config = setTypeScriptAlias(require('./tsconfig.json'), {
[...]
plugins: [
new ContextReplacementPlugin(
// The (\\|\/) piece accounts for path separators in *nix and Windows
/angular(\\|\/)core(\\|\/)(esm(\\|\/)src|src)(\\|\/)linker/,
root('./ClientApp')
),
new TsConfigPathsPlugin({
tsconfig: 'tsconfig.json'
}), [...]
使用这些帮助功能:
function setTypeScriptAlias(tsConfig, config) {
var newConfig = clone(config);
newConfig = newConfig || {};
newConfig.resolve = newConfig.resolve || {};
newConfig.resolve.alias = newConfig.resolve.alias || {};
var tsPaths = tsConfig.compilerOptions.paths;
for (var prop in tsPaths) {
newConfig.resolve.alias[prop] = root(tsPaths[prop][0]);
}
return newConfig;
}
function root(args) {
args = Array.prototype.slice.call(arguments, 0);
return path.join.apply(path, [__dirname].concat(args));
}
最后在tsconfig.js中定义路径
"compilerOptions": {
[...]
"paths": {
"app": [ "./ClientApp/app" ]
},[...]
然后你可以通过&#34; app&#34;路径如
import { AppModule } from 'app';
答案 4 :(得分:0)
我可以通过将以下内容添加到tsconfig.app.json
中来使其工作:
"compilerOptions": {
"baseUrl": "./",
...
}
,如https://www.typescriptlang.org/v2/en/tsconfig#moduleResolution中所述。它已经在tsconfig.json
中,但显然仅用于IDE integration。