Preact-cli: htmlWebpackPlugin with the build command

Created on 17 Nov 2017  路  11Comments  路  Source: preactjs/preact-cli

Hi there :)

Do you want to request a feature or report a bug?
Bug

What is the current behavior?
The build with prerendering and custom constants on top of the HtmlWebpackPlugin webpack plugin fail to build with this error: TypeError: Cannot read property CONSTANT_NAME

If the current behavior is a bug, please provide the steps to reproduce.
Here is my preact.config.js

export default function(config, options, helpers) {
  'use strict';
  const {plugin} = helpers.getPluginsByName(config, 'HtmlWebpackPlugin')[0] ||聽{};
  if (plugin) {
    plugin.options.constant = require(`./config/constant.json`); // returns {"CONSTANT_NAME": "toto"}
    helpers.setHtmlTemplate(config, 'index.tpl.html');
  }
  config.output.publicPath = '/';
}

Where constant.json returns an object of api keys and it's used in the template like this: <%= htmlWebpackPlugin.options.constant.CONSTANT_NAME %>

What is the expected behavior?
It works well with preact dev and <%= htmlWebpackPlugin.options.constant.CONSTANT_NAME %> is replaced by the proper key. So it should behave the same with the build command.

Please mention other relevant information.

  • node version: 6.5.9
  • npm version 3.10.10
  • Operating system: max os
bug stale

Most helpful comment

Well, it's what DefinePlugin is made for, and it's no different than injecting a NODE_ENV value. It's also more of a common practice to go thru the process.env.

Aside from that, not very different. Doesn't matter as long as it works for you~!

All 11 comments

If #430 lands, it will make doing this much easier.

Indeed but i would still need this to work because my file constant.json change at build time based on the environment. And they are globals constants, not page specific :s

You can require the constants.json file directly in your code and then use DefinePlugin to inject the env values.

Ok interesting, i manage to make it works with DefinePlugin.
Here it is:

import keys from './config/constant.json';
export default function(config, options, helpers) {
  'use strict';
  const {plugin} = helpers.getPluginsByName(config, 'HtmlWebpackPlugin')[0] || {};
  if (plugin) {
    helpers.setHtmlTemplate(config, 'index.tpl.html');
  }
  config.plugins.push(
      new helpers.webpack.DefinePlugin({
        apiKeys: keys,
      })
  );
  config.output.publicPath = '/';
}

And then in the template: <%= apiKeys.MY_KEY %>

I wonder if i misread the doc or if it could be improved..

But, even though it works for me now, the behavior described in the ticket is still unsolved i guess and it could leads to other bugs, so I'll let you close the ticket if you think it's not relevant.

I meant requiring the constant.json inside your bundle.

const ENV = require('./constant.json');
window.MY_VALUE = ENV.secret;

This way you wouldn't have to worry about the template stuff.

Also, you can pass --template index.tpl.html instead of going thru preact.config.js

I'd suggest this approach instead:

// preact.config.js

const { API_URL, CDN_URL } = process.env;

module.exports = function (config) {
  config.plugins.push(
      new DefinePlugin({
        'process.env.API_URL': JSON.stringify(API_URL || 'https://dev/api'),
        'process.env.CDN_URL': JSON.stringify(CDN_URL || 'https://dev-cdn.com')
      })
  );
}

Your CI systems probably inject process.env for you already. But if they don't you can use dotenv (or similar) to do it manually.

What are the benefits of your last solution over mine ?
I feel like it's more complicated to get the key in the JS files when i can still import the json there with my solution.

ps: Thank for the tips about the template, and I was already doing it.. copy/past ftw 馃

Well, it's what DefinePlugin is made for, and it's no different than injecting a NODE_ENV value. It's also more of a common practice to go thru the process.env.

Aside from that, not very different. Doesn't matter as long as it works for you~!

Okay, many thanks for those informations! :)

Is this okay to close @guillaumebreux ?

For me it is even though the initial reported bug still apply, but i'am not sure it is relevant.

So it's your call to close it :)

Many thanks @lukeed for sharing your preact.config.js file, I was looking everywhere and couldn't find any way to pass a configuration as environnement variable with preact cli, your answer just did it, thanks 馃憤

This example should be in the doc!

Was this page helpful?
0 / 5 - 0 ratings