質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.34%

CommonJSとESのimport/exportを同じファイルに書くとエラーが発生する

受付中

回答 1

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 1,353

4321bocya

score 13

やりたいこと

  1. CommonJSの形式でexportされた(module.exportsの形)複数のモジュールをjsファイルでimportし、一つのモジュールにまとめて再度exportする
  2. 1で再度exportされたモジュールをtsファイルでimportする

※条件として1で記載したmodule.exportsの形式でexportされたモジュールをESのexportの書き方に変えることはできない

ご教示お願いします。

現在のコード

module.exportしているファイル(hoge.js)

前提としてこのファイルのexport方法は変更できないものとします。

const hoge = {
  key : 'value',
}
module.exports = hoge
複数のモジュールをimportして再度exportするファイル(sample.js)
const hoge = require('./hoge');
const fuga = require('./fuga');
const sample = {
  ...hoge,fuga
};
module.exports = sample

importしたいファイル(import.ts)

import sample from './sample';
// hoge.jsとfuga.jsのJSONを出力したい
console.log(sample);

現在のエラーメッセージ

アプリケーション起動時にブラウザのコンソールに以下のメッセージが出力されます。
怒られているのはhoge.jsです。

Uncaught TypeError: Cannot assign to read only property 'exports' of object '#<Object>'

試したこと

以下の記事を参考にしました。

①import.tsでのimport方法を変える

以下のように修正しましたが、エラーが発生します。

import sample from './sample';
↓
const sample = require('./sample');

エラーメッセージ(アプリケーション起動時)
import方法をrequiteに変更してもhoge.jsで同じメッセージで怒られます。

Uncaught TypeError: Cannot assign to read only property 'exports' of object '#<Object>'
②sample.jsのexport方法を変える

sample.jsのexport方法をmodule.exportsからexport defaultとする。

module.exports = sample
↓
export default sample


エラーメッセージは変わらずでした。
hoge.jsで同じメッセージで怒られます。

Uncaught TypeError: Cannot assign to read only property 'exports' of object '#<Object>'

ビルド関連

babel.config.js

module.exports = {
  presets: [
    '@vue/app'
  ]
}


tsconfig.json

{
  "compilerOptions": {
    "target": "esnext",
    "module": "esnext",
    "strict": true,
    "jsx": "preserve",
    "importHelpers": true,
    "moduleResolution": "node",
    "experimentalDecorators": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "sourceMap": true,
    "baseUrl": ".",
    "types": [
      "webpack-env"
    ],
    "paths": {
      "@/*": [
        "src/*"
      ]
    },
    "lib": [
      "esnext",
      "dom",
      "dom.iterable",
      "scripthost"
    ]
  },
  "include": [
    "src/**/*.ts",
    "src/**/*.tsx",
    "src/**/*.vue",
    "tests/**/*.ts",
    "tests/**/*.tsx"
  ],
  "exclude": [
    "node_modules"
  ]
}


telint.json

{
  "defaultSeverity": "warning",
  "extends": [
    "tslint:recommended"
  ],
  "linterOptions": {
    "exclude": [
      "node_modules/**"
    ]
  },
  "rules": {
    "quotemark": [true, "single"],
    "indent": [true, "spaces", 2],
    "interface-name": false,
    "ordered-imports": false,
    "object-literal-sort-keys": false,
    "no-consecutive-blank-lines": false,
    "max-line-length": [true, {"limit": 120, "ignore-pattern": "^import | ^export {(.*?)}"}]
  }
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • maisumakun

    2019/07/26 15:30

    ビルド環境はどのように構築していますか?

    (TypeScriptコンパイラでJSも処理している、あるいはTypeScriptは型チェックが終わればBabelで型を引き剥がしてWebpackに投げている、など処理方法によってモジュールまわりの挙動は大きく変わってきます)

    キャンセル

  • 4321bocya

    2019/07/26 16:12 編集

    >ビルド環境はどのように構築していますか?
    前提として今、起動したアプリケーションはvue-cliで構築したもので
    ビルド設定は基本的にvue-cliのデフォルトのままです。

    コンパイル、ビルド周りの設定ファイルを追加しました。
    お手数おかけしますが、ご確認お願い致します。

    キャンセル

回答 1

0

  • webpack 4
  • babel 7

ESModules の import / export  と CommonJS の module.exports / require が混在するとwebpackで解釈ができずにエラーが発生しがちなので、揃えてあげるのが良さそうに思います。

You can mix require and export. You can't mix import and module.exports.
Cannot assign to read only property 'exports' of object '#<Object>' (mix require and export) #4039

ただ本件は混在してないにもかかわらずこのエラーが発生しているようで、原因はちょっと分からないのですが sample.js で読み込んだモジュールを ... で複製したものを module.exports しているのが鬼門になっている。

下記は同じようなエラーになります

// sample.js
const hoge = require('./hoge');
const sample = {...hoge};
module.exports = sample;

// import.ts
const sample = require('./sample');
=> 🙅‍♀️

// import.ts
import sample from './sample'; 
=> 🙅‍♀️

スプレッド演算子で複製しなければ問題なく動作するので…

const hoge = require('./hoge');
const sample = {hoge};
module.exports = sample;

// import.ts
const sample = require('./sample');
=> 🤔

// import.ts
import sample from './sample'; 
=> 🤔

sample.js を export default にすればうまく動作するかと思います

// sample.js
const hoge = require('./hoge');
const sample = {...hoge};
export default sample;


// import.ts
import sample from './sample'; 
=> 🙆‍♀️

// import.ts
const sample = require('./sample');
=> require でも 🙆‍♀️

ESModules と CommonJS の方式が同じファイルで混在しているので、hoge の読み込みも import で揃えた方が良さそうに思います。

// sample.js
import hoge from './hoge';
const sample = {...hoge};
export default sample;

// import.ts
import sample from './sample'; 
=> 🙆‍♀️

// import.ts
const sample = require('./sample');
=> require でも 🙆‍♀️

※ 同じファイルで import したものを module.exports するとすべからく下記のエラーが発生します。

Uncaught TypeError: Cannot assign to read only property 'exports' of object '#<Object>'

 

// sample.js
import hoge from './hoge';
const sample = {...hoge};
module.exports = sample;

// import.ts
import sample from './sample'; 
=> 🙅‍♀️

// import.ts
const sample = require('./sample');
=> 🙅‍♀️
// sample.js
import hoge from './hoge';
const sample = {hoge};
module.exports = sample;

// import.ts
import sample from './sample'; 
=> 🙅‍♀️

// import.ts
const sample = require('./sample');
=> 🙅‍♀️

cf.
https://github.com/webpack/webpack/issues/4039
https://chaika.hatenablog.com/entry/2019/02/04/083000
https://tech-1natsu.hatenablog.com/entry/2017/10/21/142210

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.34%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る