dotenv not working with serverless/webpack - javascript

EDIT: If I log out dotenv.config() I get an error of : Error: ENOENT: no such file or directory, open '/Users/myPathToApplication/.webpack/test/.env'
I am bundling my serverless handler in order to use es6/es7 code. I have some env variables that I am trying to use as well. The problem is it seems that dotenv is not working when I bundle the handler.
For example one of the utils I am using is connecting mongoose to my application. In here I store the DB_URI as an env variable. import envdotjs from 'envdotjs';
import mongoose from 'mongoose';
mongoose.Promise = global.Promise;
require('dotenv').config();
let isConnected;
const connectToDatabase = () => {
if (isConnected) {
console.log('=> using existing database connection');
return Promise.resolve();
}
console.log('=> using new database connection');
return mongoose.connect(process.env.DB_URI).then(db => {
isConnected = db.connections[0].readyState;
});
};
module.exports = {
connectToDatabase
};
However the DB_URI is undefined and the code breaks.
Here is my webpack:
const slsw = require('serverless-webpack');
const nodeExternals = require('webpack-node-externals');
module.exports = {
entry: slsw.lib.entries,
target: 'node',
devtool: 'source-map',
externals: [nodeExternals()],
mode: slsw.lib.webpack.isLocal ? 'development' : 'production',
module: {
rules: [
{
test: /\.js$/,
loader: 'babel-loader',
include: __dirname,
exclude: /node_modules/
}
]
}
};
I am running this in order to use es6/7 on serverless handler which is working just fine. But the env variables are breaking. I also tried using a module called envdotjs and got the same results that the env variables are undefined so I don't think this is a problem with dotenv.

I found a package dotenv-webpack also recommended by #apokryfos. Just require it in const Dotenv = require('dotenv-webpack') and include it in the webpack.config.js.
module.exports = {
...
plugins: [new Dotenv()]
}
Just include your .env in the root with your webpack.config.js and you can declare your process.env. anywhere you need to with no other configuration.

Related

Using environment variables in split webpack configuration

I'm reading the webpack docs on environment variables. In order to use the env variable they convert the module.exports into a function.
How do I perform this "conversion into a function" if my module.exports object is split across two files:
webpack.common.js:
const path = require("path");
const Dotenv = require("dotenv-webpack");
//Other stuff.
module.exports = {
entry: {
app: "./src/app.tsx",
},
module: {
rules: loaders,
},
resolve: {
extensions: [".tsx", ".ts", ".js", ".jsx"],
},
output: {
filename: "main.bundle.js",
path: path.resolve(path.resolve(), "../dist"),
},
plugins: [new Dotenv({ path: "../backend/.env.development" })], //Wish to be able to change the path depending on 'env'
};
webpack.dev.js:
const path = require("path");
const { merge } = require("webpack-merge");
const common = require("./webpack.common.js");
const fs = require("fs");
module.exports = merge(common, {
devtool: "inline-source-map",
mode: "development",
devServer: {
static: {
directory: path.join(path.resolve(), "../dist"),
},
port: 3000,
http2: true,
https: {
key: fs.readFileSync("../pathtokey.pem"),
cert: fs.readFileSync("../pathtocert.pem"),
},
},
});
If I simply convert both objects in both files into functions, it errors out.
The reason for my attempt is that I'm trying to gain access to a webpack environment variable env so that I may tell dotenv-webpack which .env file to refer to (either "development" or "production", in webpack.common.js). I'm also new to this so any tips are appreciated.

npm build to two dist folder

I have a Gatsbyjs project and I'm trying to build into 2 different folders public and production.
The public folder will be used for development purposes.
I have tried npm build ./production. It is building into the public folder.
Despite not being a common purpose, you can achieve that changing you gatsby-node.js via Gatsby API (onPostBuild):
const path = require("path")
const fs = require("fs")
exports.onPreInit = () => {
if (process.argv[2] === "build") {
fs.rmdirSync(path.join(__dirname, "dist"), { recursive: true })
fs.renameSync(
path.join(__dirname, "public"),
path.join(__dirname, "public_dev")
)
}
}
exports.onPostBuild = () => {
fs.renameSync(path.join(__dirname, 'public'),
path.join(__dirname, 'dist'), { overwrite: true })
fs.renameSync(
path.join(__dirname, "public_dev"),
path.join(__dirname, "public")
)
}
In the example above, you will output in/dist when running gatsby build command.
Useful GitHub issues:
https://github.com/gatsbyjs/gatsby/issues/18975
https://github.com/gatsbyjs/gatsby/issues/14703

webpack.optimize.UglifyJSPlugin does not work while uglifyjs-webpack-plugin works

I have 2 files app.js & math.js
It contains the following code -
app.js
import { sum } from "./math";
console.log("💩");
console.log(sum(2, 3));
math.js
export const sum = (a, b) => a + b;
export const multiply = (m, n) => m * n;
webpack.config.js
const path = require("path");
const webpack = require("webpack");
const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
const config = {
entry: "./app.js",
output: {
path: path.resolve(__dirname, "dist"),
filename: "bundle.js"
},
plugins: [
new UglifyJsPlugin()
// new webpack.optimize.UglifyJsPlugin() doesn't work
]
};
module.exports = config;
The complete code is available at https://github.com/deadcoder0904/webpack-treeshake
The problem is UglifyJsPlugin works but webpack.optimize.UglifyJsPlugin() doesn't work
My webpack version is v3.11.0
Posting answer to my own question. Thanks #str for helping out.
I was using different versions of Uglify JS, not sure if that was the problem.
So I tried installing webpack version 4 which is now in beta so I had to do install webpack#next. Also, webpack-cli is now its own package so I had to install it too. Earlier, it was bundled with webpack itself.
After installing both webpack#next & webpack-cli, I changed my webpack.config,js to look like -
webpack.config,js
const path = require("path");
const webpack = require("webpack");
const config = {
entry: "./app.js",
output: {
path: path.resolve(__dirname, "dist"),
filename: "bundle.js"
}
};
module.exports = config;
And ran the following to generate bundle with TreeShaking
webpack --optimize-minimize --mode production
The complete code is available at https://github.com/deadcoder0904/webpack-treeshake
Checkout my other answer to TreeShake with Lodash which does all the treeshaking

How to create/generate/export a file from my webpack 2 config to be used inside of my React code?

I am passing in NODE_ENV variables into my webpack.config from package.json in order to return an object that either contains API endpoints for localhost or production.
1) package.json
"scripts": {
"dev": "NODE_ENV=development webpack-dev-server --history-api-fallback",
"prod": "NODE_ENV=production webpack -p",
"build": "NODE_ENV=production webpack -p"
}
2) endpoints.js
function endpoints(env) {
let prefix = env === 'development' ? 'http://localhost' : '';
return {
"login": `${prefix}/app/api/login`
}
}
module.exports = endpoints;
3) webpack.config
const webpack = require('webpack')
const HtmlWebpackPlugin = require("html-webpack-plugin");
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const CopyWebpackPlugin = require("copy-webpack-plugin");
const path = require("path");
const dist = path.resolve(__dirname, "dist");
const src = path.resolve(__dirname, "src");
const endpoints = require("./src/endpoints");
const api = endpoints(process.env.NODE_ENV);
console.log('webpack api', api);
module.exports = {
context: src,
entry: [
"./index.js"
],
output: {
path: dist,
// ....
Here below I can see the console.log of the const api.
Now my question is, how do I now generate or export out an actual file api to be used inside of my src/services/api file:
import axios from 'axios'
// import api from '../../webpack.config' <-- ?
// import api from '../../api.js <-- ?
const log = (method, err) => {
console.error(`%c${method}`, 'background: #393939; color: #F25A43', err);
return null;
};
export const userLogin = (username, password) => {
const post_data = { username, password };
return axios.post('http://localhost/app/api/login', post_data) // <-- api to be used here
.then(res => res)
.catch((err) => log('api.userLogin', err));
};
I think this is an XY problem. You could generate the files with a bit of Node (something like fs.writeFileSync('api.js', contents), or you could do it with a bit of shell scripting, but you could also just use env in your code using DefinePlugin (example: new webpack.DefinePlugin({ env: JSON.stringify(process.env.NODE_ENV) }). Then you'd be able to access env in your code directly.

Webpack-Dev-Server With Gulp Not Reloading After Code Change

im new to webpack and im trying to get it to work with gulp. i am using the guide found at the following link, but it doesnt seem to be working:
https://webpack.github.io/docs/usage-with-gulp.html
can anyone tell me which part of my configuration is wrong?
gulpfile.js
import gulp from 'gulp';
import webpack from 'webpack';
import gutil from "gulp-util";
import WebpackDevServer from "webpack-dev-server";
import webpackConfig from './webpack.config';
gulp.task("dev-server", function(callback) {
// Start a webpack-dev-server
var compiler = webpack(webpackConfig);
new WebpackDevServer(compiler, {
}).listen(4000, "localhost", function(err) {
if(err) throw new gutil.PluginError("webpack-dev-server", err);
// Server listening
gutil.log("[webpack-dev-server]", "http://localhost:4000/webpack-dev-server/index.html");
// keep the server alive or continue?
// callback();
});
});
webpack.config.js
const path = require("path");
module.exports = {
watch: true,
entry: {
app: __dirname+'/dev/index.js'
},
output: {
path: path.join(__dirname, "dist"),
filename: '[name].js'
},
module: {
loaders: [
{test: /\.js$/, loaders: ['babel']},
{test: /\.scss$/, loaders: ["style", "css", "sass"]}
]
}
}
There are differences between the Node.js API and the CLI for webpack dev server. You are using the Node.js API so should see here: https://webpack.js.org/guides/hot-module-replacement/#via-the-node-js-api
Try something along these lines inside the gulp task defining function:
// Add entry points for '/webpack-dev-server/client/index.js' necessary for live reloading
WebpackDevServer.addDevServerEntrypoints(webpackConfig, { ... dev-server-options ...});
// Start a webpack-dev-server
var compiler = webpack(webpackConfig);
new WebpackDevServer(compiler, {
}).listen(4000, "localhost", function(err) {
if(err) throw new gutil.PluginError("webpack-dev-server", err);
// Server listening
gutil.log("[webpack-dev-server]", "http://localhost:4000/webpack-dev-server/index.html");
// keep the server alive or continue?
// callback();
});
Essentially add the one line WebpackDevServer.addDevServerEntrypoints(webpackConfig, { ... dev-server-options ...}); to the beginning of your task function. This will add "/webpack-dev-server/client/index.js" as an entry to your webpack config and is needed for live reloading.

Categories

Resources