View the example project on GitHub (opens new window)

package.json







 








 


 



















{
  "name": "frontend-webpack-project",
  "version": "0.0.0",
  "license": "MPL-2.0",
  "private": true,
  "scripts": {
    "dev": "cross-env NODE_ENV=development webpack-dev-server",
    "build": "cross-env NODE_ENV=production webpack --mode production",
    "clean": "rm -rf ./dist",
    "test": "jest"
  },
  "dependencies": {
    "@app-config/main": "2"
  },
  "devDependencies": {
    "@app-config/webpack": "2",
    "@lcdev/tsconfig": "0.2",
    "cross-env": "7",
    "cypress": "6",
    "html-webpack-plugin": "4",
    "serve": "11",
    "ts-loader": "8",
    "typescript": "4",
    "webpack": "4",
    "webpack-cli": "3",
    "webpack-dev-server": "^3.2"
  },
  "jest": {
    "preset": "@lcdev/jest",
    "testPathIgnorePatterns": [
      ".yarn-cache",
      "node_modules",
      "dist",
      "cypress"
    ]
  }
}

webpack.config.js



 




















 



 













const path = require('path');
const HtmlPlugin = require('html-webpack-plugin');
const { default: AppConfigPlugin } = require('@app-config/webpack');

// Important parts are in module->rules (the AppConfigPlugin.loader), and plugins
// AppConfigPlugin relies on HtmlPlugin (html-webpack-plugin), when using headerInjection

const appConfigOptions = {
  headerInjection: true,
};

module.exports = {
  mode: 'development',
  entry: './src/index.ts',
  output: {
    publicPath: '/',
    filename: 'main.js',
    path: path.resolve(__dirname, 'dist'),
  },
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        use: 'ts-loader',
        exclude: /node_modules/,
      },
      {
        test: AppConfigPlugin.regex,
        use: { loader: AppConfigPlugin.loader, options: appConfigOptions },
      },
    ],
  },
  plugins: [new HtmlPlugin(), new AppConfigPlugin(appConfigOptions)],
  devServer: {
    host: '0.0.0.0',
    port: 8080,
    disableHostCheck: true,
    historyApiFallback: true,
  },
};

index.ts

 









import { config } from '@app-config/main';

// here simply to demonstrate how config is loaded in
document.body.innerHTML = JSON.stringify(config);

// notice that TypeScript knows the type of externalApiUrl
console.log('externalApiUrl:', config.externalApiUrl);

// if you're running the dev server, try changing config values! it should auto-reload

.app-config.schema.yml

type: object
additionalProperties: false

required:
  - externalApiUrl

properties:
  externalApiUrl:
    type: string
    format: uri

.app-config.meta.yml

generate:
  - file: './src/@types/lcdev__app-config/index.d.ts'

.app-config.yml

externalApiUrl: https://example.com

Generated Type File






 
 
 



 


// AUTO GENERATED CODE
// Run app-config with 'generate' command to regenerate this file

import '@app-config/main';

export interface Config {
  externalApiUrl: string;
}

// augment the default export from app-config
declare module '@app-config/main' {
  export interface ExportedConfig extends Config {}
}