Preact-cli: Environment variables in preact

Created on 19 Mar 2019  路  5Comments  路  Source: preactjs/preact-cli

Is there a way to inject secret environment variables in preact ? I found an old issue. Is this still the preferred way ? Are there any new ways ? The issue lists two options 1) webpack 2) plugin.

https://github.com/developit/preact-cli/issues/463

question

Most helpful comment

const { parsed } = require('dotenv-safe').config();

export default function(config, env, helpers) {
  // dotenv injection
  const { plugin } = helpers.getPluginsByName(config, 'DefinePlugin')[0];
  Object.assign(
    plugin.definitions,
    Object.keys(parsed).reduce(
      (env, key) => ({
        ...env,
        [`process.env.${key}`]: JSON.stringify(parsed[key]),
      }),
      {}
    )
  );
}

All 5 comments

Nothing new, I use dotenv-safe, if you want I can send you a snipped for preact.config.js

Thank you @ForsakenHarmony. Can you please do that ?

const { parsed } = require('dotenv-safe').config();

export default function(config, env, helpers) {
  // dotenv injection
  const { plugin } = helpers.getPluginsByName(config, 'DefinePlugin')[0];
  Object.assign(
    plugin.definitions,
    Object.keys(parsed).reduce(
      (env, key) => ({
        ...env,
        [`process.env.${key}`]: JSON.stringify(parsed[key]),
      }),
      {}
    )
  );
}

I can't make it work.

I tried the following:

import { resolve } from 'path'
import { TsconfigPathsPlugin } from 'tsconfig-paths-webpack-plugin'
import envVars from 'preact-cli-plugin-env-vars'

export default {
  /**
   * Function that mutates the original webpack config.
   * Supports asynchronous changes when a promise is returned (or it's an async function).
   *
   * @param {object} config - original webpack config.
   * @param {object} env - options passed to the CLI.
   * @param {WebpackConfigHelpers} helpers - object with useful helpers for working with the webpack config.
   * @param {object} options - this is mainly relevant for plugins (will always be empty in the config), default to an empty object
   **/
  webpack(config, env, helpers, options) {
    // Switch css-loader for typings-for-css-modules-loader, which is a wrapper
    // that automatically generates .d.ts files for loaded CSS
    helpers.getLoadersByName(config, 'css-loader').forEach(({ loader }) => {
      loader.loader = 'typings-for-css-modules-loader'
      loader.options = Object.assign(loader.options, {
        camelCase: true,
        banner:
          '// This file is automatically generated from your CSS. Any edits will be overwritten.',
        namedExport: true,
        silent: true
      })
    })

    envVars(config, env, helpers)

    config.resolve.plugins = [
      ...(config.resolve.plugins || []),
      new TsconfigPathsPlugin({ extensions: config.resolve.extensions })
    ]

    // Use any `index` file, not just index.js
    config.resolve.alias['preact-cli-entrypoint'] = resolve(
      process.cwd(),
      'src',
      'index'
    )
  }
}

  • Webpack EnvironmentPlugin


Click to see preact.config.js

import { resolve } from 'path'
import { TsconfigPathsPlugin } from 'tsconfig-paths-webpack-plugin'
import { EnvironmentPlugin } from 'webpack'

export default {
  /**
   * Function that mutates the original webpack config.
   * Supports asynchronous changes when a promise is returned (or it's an async function).
   *
   * @param {object} config - original webpack config.
   * @param {object} env - options passed to the CLI.
   * @param {WebpackConfigHelpers} helpers - object with useful helpers for working with the webpack config.
   * @param {object} options - this is mainly relevant for plugins (will always be empty in the config), default to an empty object
   **/
  webpack(config, env, helpers, options) {
    // Switch css-loader for typings-for-css-modules-loader, which is a wrapper
    // that automatically generates .d.ts files for loaded CSS
    helpers.getLoadersByName(config, 'css-loader').forEach(({ loader }) => {
      loader.loader = 'typings-for-css-modules-loader'
      loader.options = Object.assign(loader.options, {
        camelCase: true,
        banner:
          '// This file is automatically generated from your CSS. Any edits will be overwritten.',
        namedExport: true,
        silent: true
      })
    })

    config.plugins = [
      ...(config.plugins || []),
      new EnvironmentPlugin({
        PROTOCOL: 'http',
        API_URL: 'foo.bar/api'
      })
    ]
    config.resolve.plugins = [
      ...(config.resolve.plugins || []),
      new TsconfigPathsPlugin({ extensions: config.resolve.extensions })
    ]

    // Use any `index` file, not just index.js
    config.resolve.alias['preact-cli-entrypoint'] = resolve(
      process.cwd(),
      'src',
      'index'
    )
  }
}

  • And your snippet above where console.log(parsed) actually shows my env vars

All these solutions have the same result, my env vars are undefined under process.env in my code.

preact-cli 2.2.1
node v12.10.0

Any thoughts @ForsakenHarmony ?

Well, I finally found out the problem in my setup.

At the time of the writing,
yarn global add preact-cli adds [email protected] globally and
preact create ... creates a project with [email protected] in the package.json

It seems that there is a difference between 2.x.x and 3.x.x that cause this silent error with the env vars handling.
The error being: nothing in process.env whatever I tried.

Fixed with yarn global add preact-cli@3

Was this page helpful?
0 / 5 - 0 ratings