0
votes

I have a plain webpack app, index.html, main.js, that builds just fine.

I also have a self contained javascript file iframe.js, to be added to 3rd party sites that will add an iframe container referencing the webpack app:

<iframe src="https://webpack-app-domain.com/index.html">

I would like the webpack build to process iframe.js with process.env substitutions of the sort:

<%= process.env.IFRAME_URL %>

and let babel convert it to ES5 javascript and minify the output for production, but I do NOT want iframe.js to be part of the Manifest nor other dependencies introduced into the script.

It is not a webpack "entry".

If I place it in the /static folder it will get deployed, unaltered, but I cannot then customise it with any process.env variables, nor transpile, nor minify it.

If I add it as a separate webpack "entry", it gets transpiled and minified, but it also gets wrapped in a manifest function call: webpackJsonp(), yet I need the javascript to be self-contained.

How can I process this javascript file with the webpack build to satisfy my requirements?

Edit: Thanks for your replies. I applied an inline transform with the CopyWebpackPlugin to achieve my desired outcome:

const UglifyJS = require('uglify-js')
const babel = require("babel-core")

...

new CopyWebpackPlugin([
  {
    from: 'src/iframe.js',
    to: '',
    transform(content, path) {
      let js = content.toString('utf8')
      js = js.replace(new RegExp("process.env.IFRAME_URL", 'g'), env.IFRAME_URL)
        .replace(new RegExp("process.env.ROOT_API", 'g'), env.ROOT_API)
      let t = babel.transform(js, {
        presets: ["env"]
      })
      if (t.error) throw t.error
      js = t.code
      let min = UglifyJS.minify(js)
      if (min.error) throw min.error
      js = min.code.toString()
      return Buffer.from(js)
    },
  },
])

I'm not sure if this is the most elegant way but it does the job. It's duplicating the plugin pipeline that's otherwise bypassed.

2

2 Answers

1
votes

I fail to see where manifest.json relates to this question.

My answer: Use externals paired with a custom command for a separate webpack build. It's not uncommon to have more than one compilation step in a project.

If you are using package.json, then you could add this to the scripts section, and if you are using command line then just make shell script or something.

NODE_ENV=some_env webpack --config webpack.iframe.config.js --progress --colors -d --output-path 'assets' --display verbose

Then you're free to separate the dependency build from the project build, and include the results as an external in your main project.

1
votes

Have you tried using using copy-webpack-plugin?

This way you would run your normal build in parallel to copying a single file. You can use the transform method to replace the contents of the file for process.env.* and output it to the destination you want.

const CopyPlugin = require('copy-webpack-plugin');

module.exports = {
  plugins: [
    new CopyPlugin([
      {
        from: 'src/*.png',
        to: 'dest/',
        transform(content, path) {
          return optimize(content);
        },
      },
    ]),
  ],
};