ariel
ariel

Reputation: 73

How to import submodule from a ts file

I want to import a submodule from a ts file into my project. The problem is that the output file includes the entire imported file and not only the imported object.

I have an example.ts file with several exports:

export enum e1{a, b}
export enum e2{c, d}
export class exampleclass
{
    static f()
    {
        return 1;
    }
}

Update: I have another file - exampleUser.ts which imports parts from example.ts.

import {e2} from "./example";

export enum eu1{a, b}
export enum eu2{c, d}

I have a 3rd file - main.ts which imports parts from exampleUser.ts. When I use the following import

import {eu2} from "./exampleUser";

and transpile the project (using webpack) the bundled output contains un-used parts of code from exampleUser.ts and from example.ts.

tsconfig.json:

{
   "compilerOptions": {
       "target": "es3",   
       "module": "es6",
       "allowJs": true, 
       "checkJs": false,
       "sourceMap": true,
       "removeComments": true,
       "strict": true,
       "noImplicitAny": true,
       "strictNullChecks": true,
    }
}

package.json:

{
   "sideEffects": false
   "devDependencies": {
    "concurrently": "^3.6.0",
    "ts-loader": "^4.3.0",
    "typescript": "^2.8.3",
    "webpack": "^4.8.3",
    "webpack-cli": "^2.1.3"
   },
}

webpack.prod.js:

{
   mode: 'production',
   module: {
    rules: [
      {
        test: /\.tsx?$/,
        use: 'ts-loader',
        exclude: /node_modules/
      }
    ]
   },
   optimization: {
     minimize: true, // Control if the output is monified (and uglified) or not
     usedExports: true
  },
}

package-lock.json:

{
   "ts-loader": {
      "version": "4.3.0",
      "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-4.3.0.tgz",
      "integrity": "sha512-+zduqQJaeouVrGY3y6+nUG7+OE1+Q7slGCHsiQM/aITCEZ0og3GxrJVsnjM5QcWvOcu9C4VR5dP+egIyT+sNNg==",
      "dev": true,
      "requires": {
        "chalk": "2.4.1",
        "enhanced-resolve": "4.0.0",
        "loader-utils": "1.1.0",
        "micromatch": "3.1.10",
        "semver": "5.5.0"
      }
    }
}

Is it possible to import only the relevant code?

Upvotes: 0

Views: 1139

Answers (1)

Yozi
Yozi

Reputation: 12755

Things you asking about is a Tree shaking. Typescript does not do it out of the box. You use webpack which can do that. Please see how to set up it here Tree shaking

I guess it would be enough to set mode: 'production' and webpack will optimize your output

UPD:

After some discuss it was found out: with typescript's target lower than "es2015" class will be compiled to regular function. Functions could have side effect via closures, so it could be unsafe to remove "unused code" and webpack includes everything "just in case"

To tell webpack that function is safe to delete compiler could put #__PURE__ comment near the function but Typescript puts @class instead.

We can write simple webpack loader to replace @class to #__PURE__. It is a little dirty but workable solution.

module.exports = function(content) {
  return content.replace(/\/\*\* @class \*\//g, '\n /*#__PURE__*/ \n');
};

The repo with proposed loader

On my projects I prefer the following solution: typescript => ESNext javascript (ts-loader) => Es5 (babel-loader) Typescript here is for type-checking, while babel take care about es5

Upvotes: 1

Related Questions