78237


TypeScript & Polyfill 環境を作ろうと、後述の通りセットアップを行いました。  
この環境で [`UAParser.js`](https://github.com/faisalman/ua-parser-js)を利用しようと

[code]

    import { UAParser } from "ua-parser-js";
    
[/code]

と記述したのですが、ビルド時に次のような警告が出力されました。

[code]

    WARNING in ./src/main/js/index.ts 8:21-29
    export 'UAParser' (imported as 'UAParser') was not found in 'ua-parser-js' (module has no exports)
    
[/code]

また、この状態のまま実行すると、consoleに次のエラーが出力されました。

[code]

    Uncaught TypeError: ua_parser_js__WEBPACK_IMPORTED_MODULE_1__.UAParser is not a constructor
        at Module.hello (index.ts:7)
        at (index):14
    
[/code]

環境の設定が誤っているのかと思い、試しに他のパッケージ([`date-fns`](https://github.com/date-fns/date-
fns), [`sum-by`](https://github.com/queicherius/sum-
by))のインポートも試してみたところ、こちらは正常に動作しました(ので原因の目処がついていません)。

このエラーを解消し、`UAParser.js`を利用するためにはどこを修正すべきでしょうか。

[再現コードの全文はこちらになります](https://github.com/yukihane/stackoverflow-
qa/tree/master/questions/ua-parser-js-example)。

`index.ts`:

[code]

    import { UAParser } from "ua-parser-js";
    
    export const hello = () => {
      const elm = document.getElementById("client");
      if (elm) {
        const ua = navigator.userAgent;
        const parser = new UAParser(ua);
        elm.innerText = parser.getBrowser().name || "unknown";
      }
    };
    
[/code]

`package.json`:

[code]

    {
      "name": "with-ts-babel",
      "version": "1.0.0",
      "main": "index.js",
      "license": "MIT",
      "scripts": {
        "build:dev": "webpack --mode=development"
      },
      "devDependencies": {
        "@babel/core": "^7.14.6",
        "@babel/plugin-proposal-class-properties": "^7.14.5",
        "@babel/preset-env": "^7.14.7",
        "@babel/preset-typescript": "^7.14.5",
        "@types/ua-parser-js": "^0.7.36",
        "babel-loader": "^8.2.2",
        "typescript": "^4.3.5",
        "webpack": "^5.44.0",
        "webpack-cli": "^4.7.2",
        "webpack-dev-server": "^3.11.2"
      },
      "dependencies": {
        "core-js": "^3.15.2",
        "ua-parser-js": "^0.7.28"
      },
      "browserslist": [
        "defaults"
      ]
    }
    
[/code]

`webpack.config.js`:

[code]

    "use strict";
    // Generated using webpack-cli https://github.com/webpack/webpack-cli
    
    const path = require("path");
    
    const isProduction = process.env.NODE_ENV == "production";
    
    const config = {
      entry: "./src/main/js/index.ts",
      output: {
        path: path.resolve(__dirname, "build/resources/main/static"),
        library: "mylib",
      },
      plugins: [
        // Add your plugins here
        // Learn more about plugins from https://webpack.js.org/configuration/plugins/
      ],
      module: {
        rules: [
          {
            loader: "babel-loader",
            options: {
              exclude: [
                // \\ for Windows, \/ for Mac OS and Linux
                /node_modules[\\\/]core-js/,
                /node_modules[\\\/]webpack[\\\/]buildin/,
              ],
              presets: [
                [
                  "@babel/preset-env",
                  {
                    useBuiltIns: "usage",
                    corejs: "3",
                    shippedProposals: true,
                  },
                ],
                "@babel/preset-typescript",
              ],
              plugins: ["@babel/plugin-proposal-class-properties"],
            },
          },
    
          // Add your rules for custom modules here
          // Learn more about loaders from https://webpack.js.org/loaders/
        ],
      },
      resolve: {
        extensions: [".tsx", ".ts", ".js"],
      },
    };
    
    module.exports = () => {
      if (isProduction) {
        config.mode = "production";
      } else {
        config.mode = "development";
        config.devtool = "inline-source-map";
      }
      return config;
    };
    
[/code]


CC BY-SA 4.0
2021-07-14T03:22:03.220
78174
2021-07-17T05:50:25.563
2021-07-16T21:59:54.873
2808
2808
question
javascript npm webpack babeljs
UAParser.js をインポートできない


Babel はデフォルトでは、読み込むファイルを ES
モジュールだと想定しパースします[[1]](https://babeljs.io/docs/en/options#sourcetype)。一方で ua-
parser-js は CommonJS モジュールにのみ対応[[2]](https://github.com/faisalman/ua-parser-
js/issues/441)しています。この状況で babel によるトランスパイルを行うと、 babel は ua-parser-js を
`import` 文と同様の方法で読み込もうとします。しかし、 ua-parser-js は `import`
文による読み込みに対応していないため、何もエクスポートしません。

> ### sourceType[[1]](https://babeljs.io/docs/en/options#sourcetype)
>
> Parse the file using the ECMAScript Module grammar. Files are automatically
> strict, and import/export statements are allowed.

このようにして ua-parser-js の読み込みに失敗し、質問文に書かれている TypeError が発生しています。解決策は以下の 2
つが挙げられます：

  1. もしそのパッケージを babel でトランスパイルする必要がないならば、 `rule.exclude` によって当該パッケージを除外します。Babel-loader の動作が遅くなることも考慮して、 `node_modules` フォルダを含めトランスパイルするファイルは最小限にするべきです[[3]](https://github.com/babel/babel-loader#babel-loader-is-slow)。
  2. もしそのパッケージを babel でトランスパイルする必要がある場合は、 `sourceType` オプションに `unambiguous` を設定します。このオプションは読み込むファイルの内容を確認し、その結果に応じて適切な方法でファイルを読み込もうとします。

> ### sourceType[[1]](https://babeljs.io/docs/en/options#sourcetype)
>
> "unambiguous" \- Consider the file a "module" if import/export statements
> are present, or else consider it a "script".


CC BY-SA 4.0
2021-07-16T15:48:19.143
78237
2021-07-17T05:50:25.563
2021-07-17T05:50:25.563
32986
32986
78174
answer