I use swagger-codegen with the -l typescript-angular
option to generate a library of REST consumer services. The generated code looks like this (DefaultApi.ts
):
namespace API.Client {
'use strict';
export class DefaultApi {
protected basePath = 'http://localhost:7331/v1';
public defaultHeaders : any = {};
static $inject: string[] = ['$http', '$httpParamSerializer', 'basePath'];
constructor(protected $http: ng.IHttpService, protected $httpParamSerializer?: (d: any) => any, basePath?: string) {
if (basePath !== undefined) {
this.basePath = basePath;
}
}
private extendObj<T1,T2>(objA: T1, objB: T2) {
for(let key in objB){
if(objB.hasOwnProperty(key)){
objA[key] = objB[key];
}
}
return <T1&T2>objA;
}
/**
* Delete a person.
* Deletes a specified individual and all of that person's connections.
* @param id The id of the person to delete
*/
public deletePersonById (id: number, extraHttpRequestParams?: any ) : ng.IHttpPromise<{}> {/*...*/}
/* etc... */
}
}
As you can see, there are concrete classes that need to be used but are declared inside of a namespace, i.e. not import
able. My editor (VSCode) doesn't complain when I reference API.Client.DefaultApi
despite the lack of an import
because it picks up the definition as part of a declared namespace I suppose. But at run-time the browser complains that API
is not defined.
I am using webpack to bundle my code. I see a few other questions on SO that are kind of like this one, but had no luck with the answers there.
EDIT:
As requested, here are my configuration files for ts and webpack:
webpack config file:
const webpack = require('webpack');
const conf = require('./gulp.conf');
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const autoprefixer = require('autoprefixer');
module.exports = {
module: {
preLoaders: [
{
test: /\.ts$/,
exclude: /node_modules/,
loader: 'tslint'
}
],
loaders: [
{
test: /.json$/,
loaders: [
'json'
]
},
{
test: /\.(css|less)$/,
loaders: [
'style',
'css',
'less',
'postcss'
]
},
{
test: /\.ts$/,
exclude: /node_modules/,
loaders: [
'ng-annotate',
'ts'
]
},
{
test: /.html$/,
loaders: [
'html'
]
}
]
},
plugins: [
new webpack.optimize.OccurrenceOrderPlugin(),
new webpack.NoErrorsPlugin(),
new HtmlWebpackPlugin({
template: conf.path.src('index.html')
})
],
postcss: () => [autoprefixer],
debug: true,
devtool: 'source-map',
output: {
path: path.join(process.cwd(), conf.paths.tmp),
filename: 'index.js'
},
resolve: {
modules: [
path.resolve(__dirname, '../src/app'),
path.resolve(__dirname, '../node_modules')
],
extensions: [
'',
'.webpack.js',
'.web.js',
'.js',
'.ts'
]
},
entry: `./${conf.path.src('index')}`,
ts: {
configFileName: '../tsconfig.json'
},
tslint: {
configuration: require('../tslint.json')
}
};
tsconfig.json:
{
"compilerOptions": {
"baseUrl": "src/app",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"removeComments": false,
"noImplicitAny": false,
"module": "commonjs"
},
"compileOnSave": false,
"include": [
"src/**/*.ts"
],
"exclude": [
"!typings/**",
"!node_modules/**"
]
}
You have two options to fix this, an ease and another complex:
Add the following code at the end of generated code:
Now, you can use
import
in your modules without problems, eg:The idea:
Split the modular code and not modular code with differents tsconfig. Mix modular code and not modular with Salsa, webpack resolve alias and javascript support.
Tutorial:
api.js
file and reference it in yourtsconfig.generate.json
. Yes, it is a js file, it is here that Salsa gets into action. And to do this you must enableallowJs
feature in tsconfigThese files are basically to export via commonjs your generated code without touch it.
Now, note in
tsconfig.generate.json
and youroutFile
property. If you test the compiler (tsc -p tsconfig.generate.json
), you see all your generated files concatenated inmodule-generate-code.js
, and the last line must be like in this:module.exports = API.Client;
Nearly Done!
Now, you can use the
module-generate-code.js
in your own code withimport
! But how js files do not have the best definitions, then you have config a resolve.alias in webpack.config and tsconfig.jsonNow you can use your generate code without touch it:
import api from 'api';
Any doubt, here a GitHub repo using this approach. I hope I´ve helped