hard-source-webpack-plugin
hard-source-webpack-plugin copied to clipboard
Prevent update of environment variables
Expected Behavior
Environment variables should not be cached.
Actual Behavior
Environment
Is an error being thrown?
No
Steps to Reproduce
- Add an environment variable in
.envfile and use it inEnvironment.js. webpack-serveyour website- Stop
webpack-serve - Modify the environment variable in
.env - Restart
webpack-serve - The environment variable still holds the first value
Operating System, Node, and NPM dependency versions
Mac OS 10.13.5
Node 8.11.3
"devDependencies": {
"@sentry/webpack-plugin": "^1.5.2",
"@types/chai": "^4.1.4",
"@types/classnames": "^2.2.3",
"@types/jquery": "^3.2.16",
"@types/js-cookie": "^2.1.0",
"@types/lodash": "^4.14.110",
"@types/mocha": "^5.2.3",
"@types/mock-fs": "^3.6.30",
"@types/node": "^8.0.51",
"@types/query-string": "^6.1.0",
"@types/react": "^16.0.22",
"@types/react-dom": "^16.0.3",
"@types/react-intl": "^2.3.8",
"@types/react-modal": "^3.2.0",
"@types/react-router-dom": "^4.2.1",
"@types/sinon": "^5.0.1",
"@types/webrtc": "0.0.23",
"aws-sdk": "^2.266.1",
"chai": "^4.1.2",
"classnames": "^2.2.6",
"concurrently": "^3.5.1",
"css-loader": "^0.28.11",
"deploy-aws-s3-cloudfront": "^0.2.9",
"dotenv-webpack": "^1.5.7",
"electron": "2.0.5",
"electron-builder": "^20.15.1",
"electron-rebuild": "^1.8.1",
"file-loader": "^1.1.5",
"hard-source-webpack-plugin": "^0.12.0",
"html-webpack-plugin": "^3.2.0",
"ignore-styles": "^5.0.1",
"jsdom": "^11.11.0",
"jsdom-global": "^3.0.2",
"mocha": "^5.2.0",
"mocha-webpack": "^1.1.0",
"mock-fs": "^4.5.0",
"native-ext-loader": "^2.1.0",
"node-sass": "^4.9.0",
"npm-run-all": "^4.1.2",
"query-string": "^6.1.0",
"react-hot-loader": "^4.3.3",
"resolve-url-loader": "^2.3.0",
"sass-loader": "^6.0.7",
"sinon": "^6.0.1",
"source-map-loader": "^0.2.3",
"source-map-support": "^0.5.6",
"style-loader": "^0.21.0",
"ts-loader": "^4.4.1",
"ts-node": "^7.0.0",
"tslint": "^5.11.0",
"tslint-consistent-codestyle": "^1.13.2",
"tslint-loader": "3.6.0",
"tslint-react": "^3.4.0",
"typescript": "^2.8.3",
"uglifyjs-webpack-plugin": "^1.2.7",
"url-loader": "^1.0.1",
"webpack": "^4.5.0",
"webpack-cli": "^3.0.8",
"webpack-dev-middleware": "^3.1.3",
"webpack-hot-middleware": "^2.22.2",
"webpack-merge": "^4.1.3",
"webpack-obfuscator": "^0.17.3",
"webpack-serve": "^2.0.1",
"webpack-strip-block": "^0.2.0"
},
"dependencies": {
"@material-ui/core": "^1.4.2",
"apollo-boost": "^0.1.10",
"apollo-client": "^2.3.7",
"async-mutex": "^0.1.3",
"graphql": "^0.13.2",
"install": "^0.12.1",
"is-electron-renderer": "^2.0.0",
"jquery": "^3.2.1",
"js-cookie": "^2.2.0",
"lodash": "^4.17.10",
"minimist": "^1.2.0",
"mngen": "^1.1.0",
"mobx": "^3.1.5",
"mobx-react": "^4.1.3",
"npm": "^6.1.0",
"raven-js": "^3.26.3",
"react": "^16.1.1",
"react-apollo": "^2.1.9",
"react-dom": "^16.1.1",
"react-electron-web-view": "^2.0.1",
"react-hot-loader": "^4.3.3",
"react-intl": "^2.4.0",
"react-modal": "^3.5.1",
"react-router": "^4.0.0",
"react-router-dom": "^4.0.0",
"robotjs": "^0.5.1"
}
Have you tried including .env in the environmentHash?
Optimally dotenv-webpack would be reflected in the configHash. You can console.log sorted in defaultConfigHash.js if you want to find out what hard-source is hashing by default. Maybe there isn't enough detail about the DefinePlugin in the hash.
Beyond that hard-source cannot support this issue. configHash is the support mechanism and we can try to support that but a dynamic way to not cache DefinePlugin or dotenv-webpack is not possible because of how they work.
@mzgoddard How can I add dotenv-webpack to the configHash? My webpack config looks like this:
plugins: [
new Dotenv({
systemvars: true,
path: path.join(__dirname, "../.env"),
}),
new HardSourceWebpackPlugin(),
],
Have you tried including .env in the environmentHash?
Actually, this seems to be working !
Sure, but what if you aren't using .env for everything that might change across builds! (Like you have npm run start-XX, where XX targets a different API using env vars right before the command)
EX:
"scripts": {
"start-qa": "REACT_APP_ENV=qa npm-run-all -p watch-css start-js",
This worked for me w/o any 3rd party libraries. Note the recommended node-object-hash didn't for some reason.
const util = require('util');
const crypto = require('crypto');
....
new HardSourceWebpackPlugin({
configHash: webpackConfig => crypto
.createHash('md5')
.update(
JSON.stringify(
util.inspect({
webpackConfig,
reactAppVars: Object.entries(process.env).filter(([name]) =>
name.toUpperCase().includes('REACT_APP')
),
})
)
)
.digest('hex'),
environmentHash: {
root: process.cwd(),
directories: [],
files: ['package-lock.json', '.env', 'package.json'],
},
....
I really like this lib but I think something like the above should be talked about more in the docs (or even be the default) as this burned me pretty bad for awhile till I figured out what was happening.
@johnculviner I think with this approach you lose any caching when you switch between different envs. I mean I have something similar that looks like this:
"test:e2e:ci": "npm run test:e2e:ENV_1 && npm run test:e2e:ENV_2 && npm run test:e2e:ENV_3"
And in webpack config I have something like this:
{
plugins: [
// ...
new webpack.EnvironmentPlugin({
PROJECT_NAME,
PROJECT_INTL,
PROJECT_REGION_INTL,
// ...
}),
new HardSourceWebpackPlugin(),
// ...
],
resolve: {
alias: {
"@projectImages": PROJECT_IMAGES,
"@projectIntl": PROJECT_INTL,
"@projectRegionIntl": PROJECT_REGION_INTL,
}
}
}
Each different env changes values of PROJECT_NAME, PROJECT_INTL and PROJECT_REGION_INTL and because of this HardSourceWebpackPlugin writes new cache for each npm run test:e2e:ENV_X call.
It would be nice to be able to switch between envs without loosing caching possibilities but recomputing modules that rely on env.