如何解决webpack 进入生产模式时未定义的 .env 变量 env.jswebpack.server.js
我使用 dot-env NPM 包是为了将简单的变量传递给我的 webpack/express 应用程序。
当我在 webpack 的 PRODUCTION 模式下运行时,.env 中的所有变量都未定义。
我正在构建一个开发和生产 webpack 配置文件,目前有以下设置。
对于我所犯的错误以及为什么我的 .env 变量被删除的任何建议,我们将不胜感激。
-
package.json(脚本)
"buildDev": "rm -rf dist && webpack --mode development --config webpack.server.config.js && webpack --mode development --config webpack.dev.config.js","buildProd": "rm -rf dist && webpack --mode production --config webpack.server.config.js && webpack --mode production --config webpack.prod.config.js",
-
webpack.dev
const path = require("path"); const webpack = require("webpack"); const HtmlWebPackPlugin = require("html-webpack-plugin"); const MiniCssExtractPlugin = require("mini-css-extract-plugin"); const paths = require("./config/paths"); const isDevelopment = false; const Dotenv = require('dotenv-webpack'); require('dotenv').config() module.exports = { entry: { main: [ "webpack-hot-middleware/client?path=/__webpack_hmr&timeout=20000",paths.appIndexJs,],},output: { path: path.join(__dirname,"dist"),publicPath: "/",filename: "[name].js",devServer: { historyApiFallback: true,mode: "production",target: "web",devtool: "#source-map",module: { rules: [ { enforce: "pre",test: /\.(js|jsx)$/,exclude: /node_modules/,loader: "eslint-loader",options: { emitWarning: true,failOnError: false,failOnWarning: false,{ test: /\.(js|jsx)$/,include: path.resolve(paths.appSrc),loader: "babel-loader",{ // Loads the javacript into html template provided. // Entry point is set below in HtmlWebPackPlugin in Plugins test: /\.html$/,use: [ { loader: "html-loader",{ test: /\.css$/,use: ["style-loader","css-loader"],include: /node_modules/,{ test: /\.scss$/,"css-loader","sass-loader"],{ test: /\.(png|svg|jpg|gif|eot|woff|woff2|ttf)$/,use: ["file-loader"],resolve: { extensions: [".js",".jsx"],plugins: [ new HtmlWebPackPlugin({ favicon: "./src/assets/img/favicons/favicon.ico",template: "./src/html/index.html",filename: "./index.html",excludeChunks: ["server"],}),new webpack.HotModuleReplacementPlugin(),new webpack.NoEmitOnErrorsPlugin(),new Dotenv() ],};
-
webpack.prod
const path = require("path"); const webpack = require("webpack"); const HtmlWebPackPlugin = require("html-webpack-plugin"); const MiniCssExtractPlugin = require("mini-css-extract-plugin"); const paths = require("./config/paths"); const isDevelopment = false; const Dotenv = require('dotenv-webpack'); require('dotenv').config() module.exports = { entry: { main: [ "webpack-hot-middleware/client?path=/__webpack_hmr&timeout=20000",{ // Loads the javacript into html template provided. // Entry point is set below in HtmlWebPackPlugin in Plugins test: /\.html$/,use: [ { loader: "html-loader",/*{ test: /\.scss$/,use: [ { loader: 'css-loader',options: { url: false,sourceMap: true } },{ loader: 'sass-loader',options: { sourceMap: true } },] },*/ /*{ test: /\.css$/,{ test: /\.sass$/,use: [ MiniCssExtractPlugin.loader,{ loader: 'css-loader',options: { sourceMap: true } },{ test: /\.css$/,loader: [ isDevelopment ? "style-loader" : MiniCssExtractPlugin.loader,{ loader: "css-loader",options: { modules: true,sourceMap: isDevelopment,{ test: /\.(scss)$/,use: [ MiniCssExtractPlugin.loader,sourceMap: true } },] },*/ { test: /\.(png|svg|jpg|gif|eot|woff|woff2|ttf)$/,//include: path.resolve(paths.appSrc),resolve: { extensions: [".js",plugins: [ new webpack.DefinePlugin({ 'process.env': { 'NODE_ENV': JSON.stringify('production') } }),new HtmlWebPackPlugin({ favicon: "./src/assets/img/favicons/favicon.ico",new Dotenv() ],};
-
webpack.server
const path = require("path"); const webpack = require("webpack"); const nodeExternals = require("webpack-node-externals"); const HtmlWebPackPlugin = require("html-webpack-plugin"); module.exports = (env,argv) => { const SERVER_PATH = argv.mode === "production" ? "./src/server/server-prod.js" : "./src/server/server-dev.js"; return { entry: { server: SERVER_PATH,output: { path: path.join(__dirname,mode: argv.mode,target: "node",node: { // Need this when working with express,otherwise the build fails __dirname: false,// if you don't put this is,__dirname __filename: false,// and __filename return blank or / },externals: [nodeExternals()],// Need this to avoid error when working with Express devServer: { historyApiFallback: true,module: { rules: [ { // Transpiles ES6-8 into ES5 test: /\.js$/,use: { loader: "babel-loader",} ],}; };
解决方法
如果你在插件部分查看 yow webpack.prod,你就会喜欢它。 新的 webpack.DefinePlugin({ 'process.env': { 'NODE_ENV': JSON.stringify('production') } 所以基本上你是将 process.env 设置为等于 What Eva is there
解决方案
首先你需要安装两个模块
- dotenv-expand
- dotenv
$ npm i -D dotenv-expand dotenv
下一步
创建一个名为 env.js
的新文件,我的意思是名称由您决定。将文件放在 yow webpacks 所在的位置
env.js
'use strict';
const fs = require('fs');
const path = require('path');
const {NODE_ENV} = process.env.NODE_ENV;
const dotenvFile = `.env.${NODE_ENV}`;
require('dotenv-expand')(
require('dotenv').config({
path: dotenvFile,}));
const appDirectory = fs.realpathSync(process.cwd());
process.env.NODE_PATH = (process.env.NODE_PATH || '')
.split(path.delimiter)
.filter(folder => folder && !path.isAbsolute(folder))
.map(folder => path.resolve(appDirectory,folder))
.join(path.delimiter);
// set your own prefix
const PREFIX = /^ENETO_/i;
function getEnvironment() {
const raw = Object.keys(process.env)
.filter(key => PREFIX.test(key))
.reduce(
(env,key) => {
env[key] = process.env[key];
return env;
},{
NODE_ENV: process.env.NODE_ENV || 'development',PORT: process.env.PORT||3000,}
);
const stringified = {
'process.env': Object.keys(raw).reduce((env,key) => {
env[key] = JSON.stringify(raw[key]);
return env;
},{}),};
console.log("stringified",stringified);
return { raw,stringified };
}
module.exports = getEnvironment();
注意
确保添加前缀,以便所有前缀都以 PREFIX
开头
您可以设置自己的前缀
现在在每个 yow webpacks 上添加它;
webpack.server.js
/**
webpack server
*/
"use strict";
const path = require("path");
const nodeExternals = require("webpack-node-externals");
const webpack = require("webpack");
/**
* HERE IS IMPORTED ALL THE WAY TO THE BOTTOM YOU'LL SEE IT
*/
const vars = require("./env");
const { NODE_ENV } = process.env;
const entry = [path.join(__dirname,NODE_ENV === "production" ? `../src/prod.ts` : `../src/dev.ts`)];
module.exports = {
target: "node",name: "server",externals: [nodeExternals()],entry: [
require.resolve("@babel/register"),require.resolve("core-js/proposals"),require.resolve("core-js"),require.resolve("@babel/runtime-corejs3/regenerator"),require.resolve("es6-promise/auto"),...entry,],devtool: false,mode: process.env.NODE_ENV,output: {
filename: "[name]-bundle.js",chunkFilename: "[name].chunk.js",path: path.resolve(__dirname,"../bundle"),publicPath: "/",libraryTarget: "commonjs2",},resolve: {
extensions: [".ts",".tsx",".js"],module: {
rules: [
{
test: /\.tsx?$/,exclude: /node_modules/,use: [
{
loader: "babel-loader",{
test: /\.(js|mjs)$/,exclude: /@babel(?:\/|\\{1,2})runtime/,loader: require.resolve("babel-loader"),options: {
babelrc: false,configFile: false,compact: false,presets: [[require.resolve("@babel/preset-env")]],cacheDirectory: true,cacheCompression: false,sourceMaps: false,inputSourceMap: false,{
test: /\.(png|jpg|gif)$/,use: [
{
loader: "file-loader",plugins: [new webpack.DefinePlugin(vars.stringified)],};
对 yow 客户端做同样的事情,就是这样:3
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。