7

I am working on a new project with webpack. This is my first try with this tool.

I used to develop with typescript (for angularJS 1.5) since 1 year and I never had any problems relating to my namespacing.

// src/App/Core/Http/Test.ts
export namespace App.Core.Http {
      export class Test {
          public attr:any;
      }
 }

// src/App/Bootstrap.ts
import { App } from "./Core/Http/Test";
let testInstance = new App.Core.Http.Test();

What if I have more file to import. I can't import more than one "App" variable and I don't want to make alias each time I'm processing an import.

This is the case I don't want and I would like to fix :

// src/App/Bootstrap.ts
import { App } from "./Core/Http/Test";
import { App as App2 } from "./Core/Http/Test2"; // How can I import properly my namespace
let testInstance = new App.Core.Http.Test(),
    test2Instance = new App2.Core.Http.Test2();

Am I wrong with something or did I mess something about webpack ? How can I play with namespace like in PHP with webpack ?

EDIT 2016/22/07 at 6:26 PM

I learnt that it is not possible to use namespace using webpack. Why ? Because each .ts file are considered as a module with its own scope.

Module developement is required.

I've found a solution to get my file call clearer using module instead of namespace.

In my case, I have App/Core which contains Http, Service, Factory, Provider... folders. At the root of Core folder I created a index.ts file which export all my needed files with module architecture. Let's see.

// src/App/Core/index.ts
export module Http {
      export { Test } from "src/App/Core/Http/Test";
      export { Test2 } from "src/App/Core/Http/Test2";
      export { Test3 } from "src/App/Core/Http/Test3";
 }

export module Service {
      export { ServiceTest } from "src/App/Core/Service/ServiceTest";
      export { ServiceTest2 } from "src/App/Core/Service/ServiceTest2";
      export { ServiceTest3 } from "src/App/Core/Service/ServiceTest3";
}
//src/App/Core/index.ts ----> EOF 

And in another file call import the module with the alias Core.

// src/App/Bootstrap.ts
import { * as Core } from "./Core";

let TestInstance = new Core.Http.Test(),
    Test2Instance = new Core.Http.Test2(),
    TestInstance = new Core.Http.Test3();

let ServiceTestInstance = new Core.Service.Test(),
    ServiceTest2Instance = new Core.Service.Test2(),
    ServiceTestInstance = new Core.Service.Test3();

// src/App/Bootstrap.ts ----> EOF
2
  • In your example you exported classes within a module, which will result in a "TS1194: Export declarations are not permitted in a namespace" error, how did you handle it? Commented Mar 1, 2017 at 3:28
  • @hillin maybe use inport instead of export Commented Apr 18, 2018 at 6:43

3 Answers 3

5

I learnt that it is not possible to use namespace using webpack. Why ? Because each .ts file are considered as a module with its own scope.

Module developement is required.

I've found a solution to get my file call clearer using module instead of namespace.

In my case, I have App/Core which contains Http, Service, Factory, Provider... folders. At the root of Core folder I created a index.ts file which export all my needed files with module architecture. Let's see.

// src/App/Core/index.ts
export module Http {
      export { Test } from "src/App/Core/Http/Test";
      export { Test2 } from "src/App/Core/Http/Test2";
      export { Test3 } from "src/App/Core/Http/Test3";
 }

export module Service {
      export { ServiceTest } from "src/App/Core/Service/ServiceTest";
      export { ServiceTest2 } from "src/App/Core/Service/ServiceTest2";
      export { ServiceTest3 } from "src/App/Core/Service/ServiceTest3";
}
//src/App/Core/index.ts ----> EOF 

And in another file call import the module with the alias Core.

// src/App/Bootstrap.ts
import { * as Core } from "./Core";

let TestInstance = new Core.Http.Test(),
    Test2Instance = new Core.Http.Test2(),
    TestInstance = new Core.Http.Test3();

let ServiceTestInstance = new Core.Service.Test(),
    ServiceTest2Instance = new Core.Service.Test2(),
    ServiceTestInstance = new Core.Service.Test3();

// src/App/Bootstrap.ts ----> EOF
Sign up to request clarification or add additional context in comments.

Comments

3

You should not be using namespaces and modules at the same time, even if you were not using webpack you would have the same problem

a normal approach with modules is to just export the class directly:

// src/App/Core/Http/Test.ts
export class Test {
    public attr:any;
}

// src/App/Bootstrap.ts
import { Test } from "./Core/Http/Test";
let testInstance = new Test();

the other example:

// src/App/Bootstrap.ts
import { Test} from "./Core/Http/Test";
import { Test2 } from "./Core/Http/Test2";
let testInstance = new Test(),
    test2Instance = new Test2();

hope this helps :)

4 Comments

Thanks for that reply, but I have to use namespacing because it's a huge app. I'm developping the new backoffice of my enterprise. I used to develop a personnal project using Gulp and I made namespace works. Do you have any other approach to make this work ? like create a special module or concat my ts file into only one to make those as a module and import it..
if you don't use modules you can use namespaces just fine, but with modules namespaces are not necessary, and in fact will go in your way as each module is in a separate scope so your separate namespace declarations will not get merged together
So my main problem is caused by what ?I don't get it. I found out that is caused by webpack and it's module system. With this way I should have some nomenclature conflict ...
you should be using either modules or namespaces, not both. since webpack expects your files to be modules (thats why I imagine you added the imports) you need to remove all the namespace declarations and follow standard module structure, more here: typescriptlang.org/docs/handbook/modules.html
2

In TypeScript you can alias namespaces with another kind of import statement. It's pretty simple.

import { App } from "./Core/Http/Test";
import Test = App.Core.Http.Test;
import { App as App2 } from "./Core/Http/Test2";
import Test2 = App2.Core.Http.Test2;

At runtime, this is no different than const Test2 = App2.Core.Http.Test2; but at compile-time, using an import statement brings over all the type information, too.

3 Comments

Yes but as it's mentioned in my post 'What if I have more file to import. I can't import more than one "App" variable and I don't want to make alias each time I'm processing an import.' but thanks for you help anyway :) hope that helps someone
I see what you mean; you're talking about PHP's behavior where the same namespace in multiple files all get merged together into one namespace. My confusion came from the differences between PHP namespaces and TypeScript namespaces. It is possible to use namespaces in TypeScript, but they don't behave the same way as PHP's.
Yes I know, using module with TypeScript the namespace behavior isn't like with PHP because in module no data are shared with the global scope. That's why you have to import all your file one by one because each file is a module.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.