2

I have a file in my project called test.js

I don't import/require it anywhere which means my webpack won't call babel-loader for that js file.

Question: what I want is to move test.js into /dist folder, but as a compiled/transpiled. What's the best practice for it?

What I tried: I tried to use a copy-webpack-plugin and use its transform parameters before copying the file, but I can't seem to find the good babel package.

{
    from: 'test.js',
        to: '/dist/test.js',
            transform(content, path) {
        //what do I write here? 
    },
}
ankitkanojia
  • 3,072
  • 4
  • 22
  • 35
Nika Kurashvili
  • 6,006
  • 8
  • 57
  • 123

2 Answers2

0

The simplest approach I could think about is to use several entry points like this:

{
    entry: {
        a: "./your-main-stuff",
        b: "./your-single-file",
    },
    output: {
        path: path.join(__dirname, "dist"),
        filename: "[name].js"
    }
}

which will create your a.js main bundle and b.js file in __dirname/dist folder both transpiled provided you used corresponding loader(s).

And from copy-webpack-plugin docs section:

webpack-copy-plugin is not designed to copy files generated from the build process; rather, it is to copy files that already exist in the source tree, as part of the build process.

so it seems to be difficult (if possible) making it move transpiled files.

Update. If you want to output files into different folders w/o changing your src folder, additonal tools needed. For your case (just 1 file) I would write a simple script and add it into package.json script section combined with webpack call like:

"scripts": {
     "dev": "webpack && babel path-to-script.js --out-file path-to-script-compiled.js"
 }
curveball
  • 4,320
  • 15
  • 39
  • 49
  • the thing is that for entry 'a' i want it to go to the different folder in dist than the entry b. so i need multiple output. is this possible? – Nika Kurashvili Jan 30 '20 at 11:02
  • @NikaKurashvili check the discussion here https://stackoverflow.com/questions/35903246/how-to-create-multiple-output-paths-in-webpack-config – curveball Jan 30 '20 at 11:04
0

Just like in the previous answer, initially I went with the "scripts" entry in package.json that runs babel. But for a number of reasons I wanted to use webpack 5 to do the job. So after failing with webpack-copy-plugin and a good amount of digging around I came to this solution:

let config = {
    entry: [
        glob.sync(srcDir + '/**/*.js') // get all .js files from the source dir
    ],
    output : {
        filename : '[name].rem.js',  // webpack wants to bundle - it can bundle here ;) 
        path: outDir
    },
    resolve: {
        alias: {
            'app': appDir
        }
    },
    plugins: [
        new RemoveEmptyScriptsPlugin({extensions: ['js'], scriptExtensions: /\.rem\.js/}) // for all .js source files that get bundled remove the bundle .rem.js file
    ],
    module: {
        rules:[{
            test: /\.jsx?$/,
            type: 'asset/resource', // get webpack to take it out instead of bundling
            generator: {
                filename: ({filename}) => filename // return full file name so directory structure is preserved
            },
            use: {
                loader: 'babel-loader',
                options: {
                    targets: { node: 16 },
                    presets: [
                        ['@babel/preset-env', { modules: 'commonjs' /* transpile import/export */}],
                    ]
                }
            }
        }]
    }
};
// Since the code does not go through the full pipeline and imports are not getting resolved, aliases will remain in the code.
// To resolve them it takes to hack the aliases object into the babel config
config.module.rules[0].use.options.plugins.push(['babel-plugin-webpack-alias-7', {config: {resolve: {alias: config.resolve.alias}}}];

And it does a good job but beware that it takes to use the patched versions of the two plugins (unless the patches have been merged already)!