3

I'm trying to import jschardet in an Angular 11 project. The current version 3.0.0 does not run in strict mode (throws TypeError at runtime). I tried to reproduce this issue in a minimal example. Therefore, I generated a new Angular project and used the same dependencies and configuration (i.e. I use the same tsconfig.json, tsconfig.app.json, angular.json, package.json and package-lock.json in both projects). However, the TypeError only occurs in my large/original project. I failed to reproduce it in a smaller project. I guess that my large project runs jschardet in strict mode somehow (even though I didn't specified it explicitly in the mentioned files), but my new project doesn't runs jschardet in strict mode. I don't know, which files would be relevant to share to figure this out. Please let me know in the comments.

Anyhow, I wouldn't like to run my Angular app in non-strict mode, just one imported library requires non-strict mode. How can I import/call a specific library in non-strict mode?


Files, versions and further information below:

  • jscharder 3.0.0
  • TypeScript 4.0.5
  • @angular/compiler 11.1.0

src/app/app.component.ts

import { Component } from '@angular/core';
import * as jschardet from 'jschardet';

@Component({
  selector: 'app-root',
  template: `
      <input type="file" id="file" (change)="decode($event)">
  `
})
export class AppComponent {
  decode(e: any) {
    const file = e.target.files[0];
    console.log(typeof file);
    const fileReader = new FileReader();
    fileReader.onload = function() {
      const array = new Uint8Array(fileReader.result as ArrayBuffer);
      let string = "";
      for (let i = 0; i < array.length; ++i) {
        string += String.fromCharCode(array[i]);
      }
      console.log(jschardet.detect(string));
    };
    fileReader.readAsArrayBuffer(file);
  }
}

tsconfig.json

{
  "compileOnSave": false,
  "compilerOptions": {
    "importHelpers": true,
    "outDir": "./dist/out-tsc",
    "sourceMap": true,
    "declaration": false,
    "moduleResolution": "node",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "downlevelIteration": true,
    "target": "es2015",
    "typeRoots": [
    ],
    "lib": [
      "es2017",
      "dom",
      "dom.iterable"
    ],
    "types": [
      "node",
      "core-js"
    ],
    "module": "es2020",
    "baseUrl": "./"
  }
}

src/tsconfig.json

{
  "extends": "../tsconfig.json",
  "compilerOptions": {
    "outDir": "../out-tsc/app",
    "baseUrl": "./",
    "types": [ "node" ],
    "typeRoots": [ "../node_modules/@types" ]
  },
  "angularCompilerOptions": {
    "fullTemplateTypeCheck": true,
    "strictInjectionParameters": true
  },
  "files": [
    "main.ts",
    "polyfills.ts"
  ],
  "include": [
    "src/**/*.d.ts"
  ]
}

angular.json (shortened)

{
  "projects": {
    "my-app": {
      "root": "",
      "sourceRoot": "src",
      "projectType": "application",
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            "aot": true,
            "outputPath": "dist",
            "index": "src/index.html",
            "main": "src/main.ts",
            "tsConfig": "src/tsconfig.app.json",
            "polyfills": "src/polyfills.ts"
          }
        },
        "serve": {
          "builder": "@angular-devkit/build-angular:dev-server",
          "options": {
            "browserTarget": "my-app:build"
          }
        }
      }
    }
  }
}

I run both projects using ng serve.

maiermic
  • 4,764
  • 6
  • 38
  • 77

1 Answers1

0

I discovered a workaround. It is working if I use a dynamic import

const jschardet = await import('jschardet');
console.log(jschardet.detect(string));

I still don't know exactly why. If I use a regular import, the library is part of the built bundle vendor.js, which defines

"use strict";

If I use a dynamic import, the library is a separate module file that does not define

"use strict";

I'm not sure, if this workaround works in general. Please add another answer or comment if you know more.

maiermic
  • 4,764
  • 6
  • 38
  • 77