awesome-typescript-loader icon indicating copy to clipboard operation
awesome-typescript-loader copied to clipboard

how to work with Code Spliting of Webpack 2

Open jzlxiaohei opened this issue 7 years ago • 15 comments

webpack 2 use import('xx').then() to split code. But use import() in ts is invalid.

any examples to show how to use import() with webpack 2 and ts ?

jzlxiaohei avatar Jan 17 '17 13:01 jzlxiaohei

I've added the following to my lib.d.ts:

declare var System: any;

And then in my code I can just call:

System.import('./path/to/module').then((c: any) => c.default)

Works for me, combined with react-router.

dmeenhuis avatar Jan 25 '17 15:01 dmeenhuis

@dmeenhuis thanks for your answer. As far as i know, System.import is deprecated in Webpack 2. see https://github.com/webpack/webpack/issues/3098

jzlxiaohei avatar Feb 06 '17 04:02 jzlxiaohei

Ah, interesting, I didn't know that. Thanks for the heads-up! Although this seems fine for the moment, since System.import won't be removed before Webpack 3.

dmeenhuis avatar Feb 06 '17 07:02 dmeenhuis

I'm running into the same issue with Babel. I don't see a plugin to let Babel understand the new import function either. https://www.npmjs.com/package/babel-plugin-dynamic-import-webpack sorta does the trick, but converts it to require.ensure. All we really need is a means of allowing Babel to see import() and leave it alone.

joezimjs avatar Feb 09 '17 04:02 joezimjs

I had the same problem. We are building Angular 2 application, and I needed to split the app into multiple chucks to reduce the loading time. I tried to to use the new import() syntax; however, it seems that it is considered invalid syntax in typescript (even after install babel-plugin-dynamic-import-webpack). To over come this, I have installed SystemJS to my dev dependecies (using npm intsall --save-dev @types/systemjs). Then loaded the module like this

        System.import('./+layout/layout.module.ts').then(module => module.default)

TS will complain about System being deprecated, just ignore that. Run build and It will successfully split the code into chucks.

aboodz avatar Feb 19 '17 08:02 aboodz

@aboodz You don't need to install SystemJS to use System.import. Webpack already handles it.

joezimjs avatar Feb 20 '17 03:02 joezimjs

@joezimjs, I tried to remove SystemJS from dev-dependencies, but it will show a build error as below:

ERROR in [default] /home/abood/git-repo/abwab-portal/src/main/webapp/app/+content/content.module.ts:19:8 
Cannot find name 'System'.

Thinking twice.... you are right we don't need SystemJS, but we need to have a definition for System object, so the compiler doesn't complain. Therefore, installing SystemJS typing is an easy way to provide a definition for System object. Also, I believe creating a definition for System would solve this as well.

aboodz avatar Feb 20 '17 07:02 aboodz

@aboodz Ah. I didn't realize you were using TS

joezimjs avatar Feb 20 '17 13:02 joezimjs

@joezimjs Here is it. https://github.com/babel/babel/tree/master/packages/babel-plugin-syntax-dynamic-import It works fine in es6, not ts. I am looking for an answer to make the TS work fine. Does anyone know something?

yoyo837 avatar Jun 05 '17 06:06 yoyo837

You can use System.import in TS. Unfortunately webpack typings doesn't contains that part. But workaround exists:) You have to import systemjs typings. Then all should work correctly. Of course System is deprecated based on systemjs typings...

day01 avatar Jun 05 '17 06:06 day01

Since [email protected] now supports the import() syntax. So I follow the webpack Code Splitting demo. It works well in JS. But once transformed to TS, The bundle code is all in one, not splitting.

joexzh avatar Jul 13 '17 02:07 joexzh

It's because typescript itself compiles import() and webpack doesn't get it after ts compilation. There is a way to pass this step to webpack. In tsconfig, in "compilerOptions" set "module": "esnext" Not sure how stable it though.

alexichepura avatar Jul 13 '17 05:07 alexichepura

It doesn't work. I end up with the following error stack for each import. My code compiles and works fine with ts-loader.

ERROR in <file>.tsx
Module build failed: SyntaxError: <file>.tsx: Unexpected token (3:40)
  1 | import * as React from 'react';
> 2 | export const contentScreenLoad = () => import(/* webpackChunkName: "content-screen" */ '../containers/content-screen');
    |                                        ^
    at Parser.pp$5.raise (.../babylon/lib/index.js:4458:13)
    at Parser.pp.unexpected (.../babylon/lib/index.js:1765:8)
    at Parser.pp$3.parseExprAtom (.../babylon/lib/index.js:3631:50)
    at Parser.pp$3.parseExprSubscripts (.../babylon/lib/index.js:3498:19)
    at Parser.pp$3.parseMaybeUnary (.../babylon/lib/index.js:3478:19)
    at Parser.pp$3.parseExprOps (.../babylon/lib/index.js:3408:19)
    at Parser.pp$3.parseMaybeConditional (.../babylon/lib/index.js:3385:19)
    at Parser.pp$3.parseMaybeAssign (.../babylon/lib/index.js:3348:19)
    at Parser.pp$1.parseVar (.../babylon/lib/index.js:2344:24)
    at Parser.pp$1.parseVarStatement (.../babylon/lib/index.js:2173:8)
    at Parser.pp$1.parseStatement (.../babylon/lib/index.js:1865:19)
    at Parser.pp$1.parseExportDeclaration (.../babylon/lib/index.js:2670:15)
    at Parser.pp$1.parseExport (.../babylon/lib/index.js:2658:29)
    at Parser.pp$1.parseStatement (.../babylon/lib/index.js:1888:74)
    at Parser.pp$1.parseBlockBody (.../babylon/lib/index.js:2272:21)
    at Parser.pp$1.parseTopLevel (.../babylon/lib/index.js:1782:8)
    at Parser.parse (.../babylon/lib/index.js:1677:17)
    at parse (.../babylon/lib/index.js:7250:37)
    at File.parse (.../babel-core/lib/transformation/file/index.js:517:15)
    at File.parseCode (.../babel-core/lib/transformation/file/index.js:602:20)
    at .../babel-core/lib/transformation/pipeline.js:49:12
    at File.wrap (.../babel-core/lib/transformation/file/index.js:564:16)
    at Pipeline.transform (.../babel-core/lib/transformation/pipeline.js:47:17)
    at .../awesome-typescript-loader/src/index.ts:151:50

Here are my compiler options:

    "target": "es2017",
    "module": "esnext",
    "moduleResolution": "node"

Dante-101 avatar Jul 13 '17 14:07 Dante-101

Hi guys,

I'm having the same problem, and getting a bit stuck.

I'm using TS 2.4.2 and trying to do codesplitting on a route;

const Home = AsyncComponent(() => {
    return import( /* webpackChunkName: 'home' */ './pages/home')
        .then( module => module.default || module)
})

I've tried just about anything I could find, but my code is compiling and working, but the code is not split up.

I've tried;

compilerOptions: {
    "module": "commonjs" | "esnext"
    "target": "es6" | "es5"
}

Tried both 'babel-plugin-syntax-dynamic-import', 'babel-plugin-dynamic-import-webpack'. Nothing seems to get me closer to actually split up code at the moment.

~~Anyone here that has a working example so i can check what I'm missing?~~

Edit: It was late last night, and I missed something stupid lol :)

I still had a module.hot accepting a direct path to an index file which imported the modules I wanted to have lazy loaded. This made sure webpack was still including it in the bundle. So make sure that there are absolutely no other references to the lazy loaded code anywhere else.

I've got it successfully working with System.Import and using "module": "commonjs". And using import() when using "module": "esnext" and with the 'syntax-dynamic-import' plugin from babel.

thomhos avatar Jul 22 '17 23:07 thomhos

I've got it successfully working with System.Import and using "module": "commonjs". And using import() when using "module": "esnext" and with the 'syntax-dynamic-import' plugin from babel.

Hey

I am also using TypeScript, still getting error when trying to use import() in aspnet react redux app .net core 1.1, can you please share your sample code.

azamshaikh avatar Oct 07 '18 02:10 azamshaikh