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.
Related
I'm trying to run npm run build on files I've merged for a website. Unfortunately I always get this error. I think it has something to do with the paths but I'm not that good in JS/React to see where the error is.
Important part of the Index.html:
<body>
<div id="root"></div>
<script src="../src/index.js" type="text/jsx"></script>
</body>
Index.jsx
import ReactDOM from "react-dom";
import React from "react";
import App from "./components/App.jsx";
const init = async () => {};
ReactDOM.render(<App />, document.getElementById("root"));
init();
webpack.config.js
const path = require("path");
const webpack = require("webpack");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const TerserPlugin = require("terser-webpack-plugin");
function initCanisterEnv() {
let localCanisters, prodCanisters;
try {
localCanisters = require(path.resolve(
".dfx",
"local",
"canister_ids.json"
));
} catch (error) {
console.log("No local canister_ids.json found. Continuing production");
}
try {
prodCanisters = require(path.resolve("canister_ids.json"));
} catch (error) {
console.log("No production canister_ids.json found. Continuing with local");
}
const network =
process.env.DFX_NETWORK ||
(process.env.NODE_ENV === "production" ? "ic" : "local");
const canisterConfig = network === "local" ? localCanisters : prodCanisters;
return Object.entries(canisterConfig).reduce((prev, current) => {
const [canisterName, canisterDetails] = current;
prev[canisterName.toUpperCase() + "_CANISTER_ID"] =
canisterDetails[network];
return prev;
}, {});
}
const canisterEnvVariables = initCanisterEnv();
const isDevelopment = process.env.NODE_ENV !== "production";
const frontendDirectory = "websitetwo_frontend";
const frontend_entry = path.join("src", frontendDirectory, "src", "index.html");
module.exports = {
target: "web",
mode: isDevelopment ? "development" : "production",
entry: {
index: path.join(__dirname, frontend_entry).replace(/\.html$/, ".js"),
},
devtool: isDevelopment ? "source-map" : false,
optimization: {
minimize: !isDevelopment,
minimizer: [new TerserPlugin()],
},
resolve: {
extensions: [".js", ".ts", ".jsx", ".tsx"],
fallback: {
assert: require.resolve("assert/"),
buffer: require.resolve("buffer/"),
events: require.resolve("events/"),
stream: require.resolve("stream-browserify/"),
util: require.resolve("util/"),
},
},
output: {
filename: "index.js",
path: path.join(__dirname, "dist", frontendDirectory),
},
plugins: [
new HtmlWebpackPlugin({
template: path.join(__dirname, frontend_entry),
cache: false,
}),
new webpack.EnvironmentPlugin({
NODE_ENV: "development",
...canisterEnvVariables,
}),
new webpack.ProvidePlugin({
Buffer: [require.resolve("buffer/"), "Buffer"],
process: require.resolve("process/browser"),
}),
],
// proxy /api to port 8000 during development
devServer: {
proxy: {
"/api": {
target: "http://127.0.0.1:8000",
changeOrigin: true,
pathRewrite: {
"^/api": "/api",
},
},
},
static: path.resolve(__dirname, "src", frontendDirectory, "assets"),
hot: true,
watchFiles: [path.resolve(__dirname, "src", frontendDirectory)],
liveReload: true,
},
};
Error
I have already searched for the error but it didnt solved it. What is wrong? Thank you for the help!
Facing weird problem, where Webpack 5 is reading parent file and ignoring
const isDev = process.env.NODE_ENV !== 'production';
But the same line is read in another file and result is correct.
Package JSON
"build:prod": "cross-env NODE_ENV=production webpack --config internals/webpack/webpack.prod.babel.js --color -p --progress --hide-modules --display-optimization-bailout",
Webpack Config
module.exports = (env, argv) => {
return {
entry: path.join(process.cwd(), 'index.js'),
target: 'node',
mode: 'production',
module: {
rules: [
{
test: /\.jsx?$/, // Transform all .js and .jsx files required somewhere with Babel
exclude: /node_modules/,
use: {
loader: 'babel-loader',
},
},
],
},
output: {
filename: 'server.bundle.js',
path: path.resolve(process.cwd(), 'build'),
},
optimization: {
minimize: true,
minimizer: [new TerserPlugin()],
nodeEnv: 'production',
},
plugins: [
new Dotenv({
path: path.join(process.cwd(), 'config', '.env.production'), // load this now instead of the ones in '.env'
}),
new webpack.EnvironmentPlugin({
NODE_ENV: JSON.stringify('production'),
}),
],
};
};
Index
const express = require('express');
const path = require('path');
const server = express();
require('./middlewares/frontendMiddleware')(server);
frontendMiddleware
module.exports = (app, options) => {
const isDev = process.env.NODE_ENV !== 'production';
if (isDev) { // <-- Thinks NODE_ENV isDev
const addDevMiddlewares = require('./addDevMiddlewares');
addDevMiddlewares(app, webpackConfig);
} else {
const addProdMiddlewares = require('./addProdMiddlewares');
addProdMiddlewares(app, options);
}
return app;
};
addDevMiddlewares
const isDev = process.env.NODE_ENV !== 'production';
if (isDev) {
... // <-- Nicely ignores, or maybe not, but this peace of code is not present in the final build.
} else{
... // <-- Goes here. All good!
}
I tried to run the program by linking MySQL and Node.js, but fs cannot be loaded due to the following errors.
Module not found: Error: Can't resolve 'fs'
By the way, adding target:'node', causes a global is not defined error.
and add node {fs:'empty'}, causes a createConnection is not a function error.
What should I do now
webpack.config.js
const path = require('path');
module.exports = (env, argv) => {
return {
mode: 'production',
entry: {
index : path.join(__dirname, 'src' ,'index.ts'),
},
output: {
path: path.join(__dirname, 'www'),
filename: 'game.js',
library: 'game',
libraryTarget: 'umd'
},
resolve: {
extensions: ['.ts', '.js'],
modules: [
path.resolve(__dirname, 'src'),"node_modules"
]
},
module: {
rules: [
{
test : /\.ts$/,
use: [{ loader: 'ts-loader'}]
}
]
}
}
};
mysql function
function get_connection():void {
console.log("mysql : ",mysql)
console.log("mysql.createConnection", mysql.createConnection)
connection = mysql.createConnection({
host: "host",
user: "user",
password: "pass",
database: "database"
}).then(conn => {
console.log('promise-mysql createConnection.');
connection = conn;
return conn;
}).catch(err => {
console.log("promise fail:",err)
})
}
As you're keen to use webpack to bundle for node server code, you shouldn't bundle node_nodules by using this helper webpack-node-externals. So try more with these options:
var nodeExternals = require('webpack-node-externals')
target: 'node',
externals: [
nodeExternals(),
],
node: {
fs: "empty",
}
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.
I am having trouble with the fs module error in Node JS Application. I am using Webpack also,
My .js file:
const fs = require('fs');
const path = require('path');
const filePath = path.join(__dirname, '../../app/logs/logs.txt');
module.exports.displayInfo = (info, containerID = 'info-dock') => {
fs.exists(filePath, (exists) => {
if (exists) {
console.log('Present');
}
});
let message;
if (info.message) {
message = info.message;
} else {
message = 'No message supplied.';
}
};
My webpack config file :
const path = require('path');
module.exports = {
entry: './clientSide/index.js',
cache: true,
output: {
path: path.resolve(__dirname, './public/js/'),
filename: 'bundle.js',
},
module: {
loaders: [
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/,
query: {
presets: ['env'],
},
},
],
},
devtool: 'source-map',
target: 'web',
node: {
fs: "empty"
}
};
When I am trying to run and call displayInfo method in my application, on the browser's console, I get an error: ncaught TypeError: fs.exists is not a function.
Does anybody know how to correct this?