Skip to content
Advertisement

Webpack – Typescript – Babel Loader not transpiling JSON import

Setting up a new webpack build for my local setup to use across the system. Aka building my webpack setup as a private node package as all my work is literally the same so building it as a global package. Similar to the concept of laravel mix.

Anyway, I’ve gotten the webpack setup transpiling the Typescript correctly, that all looks good & works as expected when called in a browser. However, I run into an issue when I import a .json file into a TS file using import * as json from 'somewhere-over-the-rainbow.json;

Transpiled Code

(()=>{var e={27:e=>{e.exports=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}},963:e=>{function t(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}e.exports=function(e,n,r){return n&&t(e.prototype,n),r&&t(e,r),e}},536:e=>{e.exports=function(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}}},t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={exports:{}};return e[r](o,o.exports,n),o.exports}n.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return n.d(t,{a:t}),t},n.t=function(e,t){if(1&t&&(e=this(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);n.r(r);var o={};if(2&t&&"object"==typeof e&&e)for(const t in e)o[t]=()=>e[t];return o.default=()=>e,n.d(r,o),r},n.d=(e,t)=>{for(var r in t)n.o(t,r)&&!n.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},n.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),n.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},(()=>{"use strict";var e=n(27),t=n.n(e),r=n(963),o=n.n(r),i=n(536),a=n.n(i);const u=["Example"];var l=n.t(u,2);(function(){function e(){t()(this,e),a()(this,"components",void 0),this.components=l}return o()(e,[{key:"init",value:function(){this.attachComponents()}},{key:"attachComponents",value:function(){}}],[{key:"build",value:function(){console.log("TEST"),(new e).init()}}]),e})().build()})()})();

As you can see, this results in 2 “lines” being for(const t in e)o[t]=()=>e[t]; and const u=["Example"];

if I remove the .json import, the code transpiles as expected

(()=>{var e={27:e=>{e.exports=function(e,n){if(!(e instanceof n))throw new TypeError("Cannot call a class as a function")}},963:e=>{function n(e,n){for(var t=0;t<n.length;t++){var r=n[t];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}e.exports=function(e,t,r){return t&&n(e.prototype,t),r&&n(e,r),e}}},n={};function t(r){if(n[r])return n[r].exports;var o=n[r]={exports:{}};return e[r](o,o.exports,t),o.exports}t.n=e=>{var n=e&&e.__esModule?()=>e.default:()=>e;return t.d(n,{a:n}),n},t.d=(e,n)=>{for(var r in n)t.o(n,r)&&!t.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:n[r]})},t.o=(e,n)=>Object.prototype.hasOwnProperty.call(e,n),(()=>{"use strict";var e=t(27),n=t.n(e),r=t(963),o=t.n(r);(function(){function e(){n()(this,e)}return o()(e,[{key:"init",value:function(){this.attachComponents()}},{key:"attachComponents",value:function(){}}],[{key:"build",value:function(){console.log("TEST"),(new e).init()}}]),e})().build()})()})();

I’ve tweaked with the Babel Preset options endlessly, the only option that seemed to transpile my testing code without const was setting module to commonjs which felt dodgy so that’s been reverted (be good to know if this is fine).

Does anyone have any insight into this? My perception is that the Babel Loader is actually doing it’s job but the JSON is being “loaded” in after Babel has transpiled TS > ES which is causing the issue of ES6 code being present in ES5 code.

Webpack Rules & TS Config below

            module: {
                rules: [
                    {
                        test: /.tsx?$/,
                        use: {
                            loader: 'babel-loader',
                            options: {
                                plugins: [
                                    '@babel/plugin-proposal-class-properties',
                                    '@babel/plugin-proposal-object-rest-spread',
                                    '@babel/plugin-transform-runtime'
                                ],
                                presets: [
                                    '@babel/react', 
                                    '@babel/preset-typescript',
                                    [
                                        '@babel/preset-env',
                                        {
                                            targets: [
                                                '>0.25%'
                                            ]
                                        }
                                    ]
                                ]
                            }
                        },
                        exclude: /node_modules/
                    },
                    {
                        test: /.s[ac]ss/i,
                        use: [
                            miniCssExtract.loader,
                            'css-loader',
                            'sass-loader'
                        ]
                    }
                ]
            }

tsconfig.json

{
    "compilerOptions": {
        "allowJs": true,
        "baseUrl": "./src",
        "forceConsistentCasingInFileNames": true,
        "importHelpers": true,
        "jsx": "react",
        "module": "esnext",
        "moduleResolution": "node",
        "noImplicitAny": true,
        "removeComments": true,
        "resolveJsonModule": true,
        "outDir": "dist",
        "strict": true,
        "target": "es5"
    }
  }

Note: I’ve processed the output of Transpiled Code above through Babel’s online transpiler (using es2015 preset) and the output is as expected, aka all const change to var.

Thanks for any help 🙂

Advertisement

Answer

You can try this:

const json = require('path-to-file.json');
User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement