Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TypeScript conditional import via require (webpack) based on environment variable #1

Closed
topheman opened this issue May 9, 2016 · 4 comments

Comments

@topheman
Copy link
Owner

topheman commented May 9, 2016

Example code: https://github.com/topheman/angular2-sandbox/blob/master/src/bootstrap.ts#L60

I deliver two version of the bundle:

  • one fully optimized, without any devtools
  • one not minified, containing sourcemaps, but specifically, shipping dev features based on dev packages which I don't want in the production one.

The bundle is based on the env var process.env.DEVTOOLS. This works with Babel/Webpack (example on an other project)

I've tried multiple things, I can't get it to work with TypeScript ...

@jbrantly
Copy link

Take a look at https://github.com/TypeStrong/ts-loader/tree/master/test/conditionalRequire

@topheman
Copy link
Owner Author

- import {usePreMiddleware, usePostMiddleware, Middleware} from '@ngrx/store';
- import {instrumentStore} from '@ngrx/devtools';
+ import ngRxStore = require('@ngrx/store');
+ import ngRxDevtools = require('@ngrx/devtools');

if (process.env.DEVTOOLS) {
+ const ngRxStore = require('@ngrx/store');
+ const ngRxDevtools = require('@ngrx/devtools');
  // the following acts just like redux middlewares ...
  // this is the logger middleware
- const actionLog: Middleware = action => { // action is the store which acts like an observable
+ const actionLog: ngRxStore.Middleware = action => { // action is the store which acts like an observable
    return action.do(val => { // .do() is only a side-effect, it doesn't affect the value of the stream itself
      console.group(val.type);
      console.log('will dispatch', val);
    });
  };
- const stateLog: Middleware = state => {
+ const stateLog: ngRxStore.Middleware = state => {
    return state.do(val => {
      console.log('state after dispatch', val);
      console.groupEnd();
    });
  };
- providers.push(usePreMiddleware(actionLog));
- providers.push(usePostMiddleware(stateLog));
+ providers.push(<any>ngRxStore.usePreMiddleware(actionLog));
+ providers.push(<any>ngRxStore.usePostMiddleware(stateLog));

  // this is the devtools part middleware
- providers.push(instrumentStore());
+ providers.push(<any>ngRxDevtools.instrumentStore());
}

I still get the following error:

[default] /Users/Tophe/projects/front/angular2-sandbox/src/bootstrap.ts:88:33
    Property 'usePreMiddleware' does not exist on type '{}'.
[default] /Users/Tophe/projects/front/angular2-sandbox/src/bootstrap.ts:89:33
    Property 'usePostMiddleware' does not exist on type '{}'.
[default] /Users/Tophe/projects/front/angular2-sandbox/src/bootstrap.ts:92:36
    Property 'instrumentStore' does not exist on type '{}'.
  • I did const ngRxStore = require('@ngrx/store') because destructuring won't work.
  • I tried to use the Provider interface instead of <any>, I got Neither type 'Provider[]' nor type 'Provider' is assignable to the other

I tried a lot of things, it still wont work. The link you provided was nearly the only example about this use case, but it's about a user module (not a module in node_modules - even less on modules exporting more than a default function).

This is my tsconfig.json, maybe there could be something to flip:

{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "sourceMap": true,
    "noEmitHelpers": true
  },
  "exclude": [
    "node_modules",
    "typings/main.d.ts",
    "typings/main"
  ],
  "filesGlob": [
    "./src/**/*.ts",
    "!./node_modules/**/*.ts",
    "src/custom-typings.d.ts",
    "typings/browser.d.ts"
  ],
  "awesomeTypescriptLoaderOptions": {
    "resolveGlobs": true,
    "forkChecker": true
  },
  "compileOnSave": false,
  "buildOnSave": false,
  "atom": { "rewriteTsconfig": false }
}

If you have an example on conditional loading with "public" packages (not modules coming from inside your project) ... I'll try https://github.com/TypeStrong/ts-loader/tree/master/test/conditionalRequire boilerplate with simple code.

topheman added a commit that referenced this issue May 12, 2016
Related to issue #1 - You'll get the exact url of the full Travis error log.
@topheman
Copy link
Owner Author

topheman commented May 12, 2016

I have adapted my webpack.config.js on a previous commit to be able to switch between awesome-typescript-loader & ts-loader 27a7135 (not especially relevent to the problem).

Now, I have commited on the branch feature/conditional-loading the code above. You can see the error log on travis.

Basically:

ERROR in ./src/bootstrap.ts
(82,33): error TS2339: Property 'usePreMiddleware' does not exist on type '{}'.

ERROR in ./src/bootstrap.ts
(83,33): error TS2339: Property 'usePostMiddleware' does not exist on type '{}'.

ERROR in ./src/bootstrap.ts
(86,36): error TS2339: Property 'instrumentStore' does not exist on type '{}'.

Is there any way to do conditional loading with TypeScript on modules which come from node_modules and are exporting objects ?

I have read a few threads about this subject, it seems to be in discussion but not yet implemented ...

@topheman
Copy link
Owner Author

Published in v0.3.2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants