简体   繁体   中英

transform es6 to commonjs in memory and use it

At this point

  1. I have a file written in ES6 and used by create-react-app app.
  2. I want to load that file in memory transform it to commonJS and use exported values in one of my scripts that needs to be commonJS.

What I have: (inspired by react-boilerplate scripts)

 const fs = require('fs'); const { transform } = require('@babel/core'); const readFile = fileName => new Promise((resolve, reject) => { fs.readFile( fileName, 'utf8', (error, value) => (error? reject(error): resolve(value)), ); }); const extractFromFile = async() => { const presets = [ [ '@babel/preset-env', { modules: false, }, ], '@babel/preset-react' ]; const plugins = [ '@babel/plugin-transform-modules-commonjs' ]; const filename = './xyz.js'; try { const code = await readFile(filename); const output = await transform(code, { filename, presets, plugins }); // Here... ., // if i write output:code to file and read it from. i can access the exported values // but if i try something like this, const foo = require(output.code) or any other // combination that i can think off. i get undefined or errors. console.log(output) } }

The Question: How should one get exported values of that file without saving it first to file and required it back from it?

EDIT:

"...use exported values in one of my scripts that needs to be commonJS..."

What I try to achieve is to have a script that would extract react-intl messages from my project.

I found a very useful script written by the react-boilerplate project people and used it in my project.

The file that I try to load is i18n.js and in their project , it's written in commonJS with a comment

IMPORTANT: This file is used by the internal build * script extract-intl , and must use CommonJS module syntax * You CANNOT use import/export in this file.

BUT: I use create-react-app and to my knowledge (and what I tested) I cannot use modules.exports as it breaks the 'yarn run build' script and I don't want to to eject the app.

Thanks

I would probably approach this by trying to change the requirement, or by using a bundler.

But answering the question within the constraints listed, I think I'd use dynamic import in the CommonJS module. Dynamic import works outside ESM modules and is supported by all major modern browsers, thougn not sadly by Edge v44 and earlier ("Legacy Edge").

Dynamic import returns a promise that is fulfilled with the module namespace object of the ESM module (which has properties for its exports):

import("/path/to/module")
.then(mod => {
    // Use `mod.x` here
})
.catch(error => {
    // Handle module load error
});

You could even define a CommonJS wrapper for a module if you liked:

(async () => {
    module.exports = await import("/path/to/module");
})
.catch(error => {
    // Handle module load error
});

In your update to the question, you've said:

The file that I try to load is i18n.js and in their project, it's written in commonJS with a comment

IMPORTANT: This file is used by the internal build * script extract-intl, and must use CommonJS module syntax * You CANNOT use import/export in this file.

BUT: I use create-react-app and to my knowledge (and what I tested) I cannot use modules.exports as it breaks the 'yarn run build' script and I don't want to to eject the app.

That's fine, you should be able to use it via import syntax (with a bundler — in your case, Webpack, which is what create-react-app uses); all it says is that you can't use import / export syntax within the file.

If you install the file to node_modules , your create-react-app build should be able to use it, thanks to Webpack's module handling.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM