question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Add or document support for Webpack HMR

See original GitHub issue

Issue type:

  • question
  • bug report
  • feature request
  • documentation issue

nestjs-config version

1.3.21

@nestjs/common+core or other package versions

Excepted behavior

Actual behavior or outcome (for issue)

Library worked great for me on a different project. I want to use this library with a new project, but this time I am trying to use the Webpack HMR capabilities to make the app reload a lot faster. Since Nest ships with this out-of-the-box would it be nice to have some kind of recipe for supporting this flow?

I’m not familiar with the internals of this library so not sure if it’s even possible to be honest. It would be really handy to be able to use this library with HMR though!

Replication/Example

ConfigModule.resolveRootPath(__dirname).load('config/**/!(*.d).{ts,js}')

Works using yarn start with ts-node. Doesn’t work with yarn start:hmr. The module initializes but no configuration is being read. Likely because all of the configuration is being appended into the server.js and is no longer in a config folder.

Issue Analytics

  • State:open
  • Created 4 years ago
  • Reactions:3
  • Comments:12

github_iconTop GitHub Comments

3reactions
marktrancommented, Jun 8, 2019

@OLDIN

import path from 'path';
import { Module, Global } from '@nestjs/common';
import { ConfigService } from './config.service';

import { ROOT_PATH } from '../constants';
const NODE_ENV = process.env.NODE_ENV || 'development';

@Global()
@Module({
  providers: [
    {
      provide: ConfigService,
      useValue: new ConfigService(
        path.resolve(ROOT_PATH, '..', `.env.${NODE_ENV}`),
      ),
    },
  ],
  exports: [ConfigService],
})
export class ConfigModule {}
import _ from 'lodash';
import dotenv from 'dotenv';
import fs from 'fs';
import joi from '@hapi/joi';

import { RedisModuleOptions } from '../redis/redis.interface';
import { TypeOrmModuleOptions } from '@nestjs/typeorm';

import { databaseOptions } from './database.config';
import { redisOptions } from './redis.config';
import { graphQLOptions } from './graphql.config';
import { GqlModuleOptions } from '@nestjs/graphql';

export interface EnvConfig {
  [key: string]: string;
}

export class ConfigService {
  private readonly envConfig: EnvConfig;

  constructor(filePath: string) {
    let config: EnvConfig;

    if (process.env.DATABASE_URL) {
      config = process.env;
    } else {
      config = dotenv.parse(fs.readFileSync(filePath));
    }

    this.envConfig = this.validateInput(config);
  }

  public get(name: string): string {
    return this.envConfig[name];
  }

  getDatabaseOptions(): TypeOrmModuleOptions {
    return databaseOptions(
      this.envConfig.NODE_ENV,
      this.envConfig.DATABASE_URL,
      this.envConfig.TYPEORM_DROP_SCHEMA,
      this.envConfig.TYPEORM_LOGGING,
    );
  }

  getRootDomain(): string {
    const parts = this.get('HOSTNAME').split('.');
    return _.takeRight(parts, 2).join('.');
  }

  getRedisOptions(): RedisModuleOptions {
    return redisOptions(this.envConfig.NODE_ENV, this.envConfig.REDIS_URL);
  }

  getGraphQLOptions(): GqlModuleOptions {
    return graphQLOptions(
      this.envConfig.NODE_ENV,
      this.envConfig.FRONTEND_HOSTNAME,
    );
  }

  private validateInput(envConfig: EnvConfig): EnvConfig {
    const envVarsSchema: joi.ObjectSchema = joi.object({
      AIRTABLE_API_KEY: joi.string().required(),
      AIRTABLE_SALES_CRM_BASE_ID: joi.string().required(),
      DATABASE_URL: joi.string().required(),
      FRONTEND_HOSTNAME: joi.string().required(),
      GOOGLE_AUTH_CLIENT_ID: joi.string().required(),
      GOOGLE_AUTH_CLIENT_SECRET: joi.string().required(),
      HOSTNAME: joi.string().required(),
      NODE_ENV: joi
        .string()
        .valid(['development', 'test', 'production'])
        .default('development'),
      PORT: joi.number().default(5000),
      README_JWT_SECRET: joi.string().required(),
      REDIS_URL: joi.string().required(),
      SENTRY_DSN: joi.string().allow(''),
      SENTRY_ENV: joi.string().allow(''),
      SESSION_SECRET: joi.string().required(),
      TYPEORM_DROP_SCHEMA: joi.boolean().default(false),
      TYPEORM_LOGGING: joi.boolean().default(false),
    });

    const { error, value: validatedEnvConfig } = joi.validate(
      envConfig,
      envVarsSchema,
      { stripUnknown: true },
    );

    if (error) {
      throw new Error(`Config validation error: ${error.message}`);
    }

    return validatedEnvConfig;
  }
}
1reaction
bashleighcommented, Apr 18, 2019

oh I see! So it’s more about the file type than the .env file. I was presuming webpack loaded it’s own dotenv package and was loading from a different dir or something like that but it sounds like this is more file type related.

I will try and investigate. My time is rather limited at the moment though as I’m working 2 jobs and still got to release V2! If I can find some time to investigate this in the next month or 2 I will. I’ll try and get V2 published first though! After that I’ll defo have a look into it!

Read more comments on GitHub >

github_iconTop Results From Across the Web

Hot Module Replacement - webpack
Hot Module Replacement with CSS is actually fairly straightforward with the help of the style-loader . This loader uses module.hot.accept behind the scenes...
Read more >
Webpack HMR Tutorial - JavaScript Stuff
Struggling to set up HMR with Webpack? Are you finding the Webpack documentation to be lacking - particularly in the HMR section?
Read more >
hot module replacement with webpack - GitHub
Introduction. Hot Module Replacement (HMR) exchanges, adds, or removes modules while an application is running without a page reload.
Read more >
Hot Module Replacement - webpack 3 documentation
Redux HMR: No loader or plugin necessary! A simple change to your main store file is all that's required. Angular HMR: No loader...
Read more >
Webpack's Hot Module Replacement Feature Explained
When a hot update failed to replace the code in the browser, the HMR runtime will let webpack-dev-server know. The webpack-dev-server will then ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found