Webpack设置环境变量的一些误区详解

一、前言

  • 日常的前端开发工作中,至少会有两套构建环境

    • 一套开发时使用,构建结果用于本地开发调试,不进行代码压缩、打印 debug 信息、包含 sourcemap 文件等
    • 一套发布时使用,构建结果用于线上,即代码都是压缩过的、运行时不打印 debug 信息、静态文件不包括 sourcemap 等
  • webpack 4.0 版本开始引入了 mode 的概念
选项 描述
development 会将 process.env.NODE_ENV 的值设为 development。启用 NamedChunksPlugin 和 NamedModulesPlugin
production 会将 process.env.NODE_ENV 的值设为 production。启用 FlagDependencyUsagePlugin, FlagIncludedChunksPlugin, ModuleConcatenationPlugin, NoEmitOnErrorsPlugin, OccurrenceOrderPlugin, SideEffectsFlagPlugin 和 UglifyJsPlugin

二、区分开发环境/生产环境的多种方式

2.1 使用命令行

2.1.1 写法一

"scripts": {
 // 默认 mode 为 development
 "dev1": "webpack-dev-server",
 // 默认 mode 为 production,不过这样写,打包的时候会有警告
 "build1": "webpack",
}

以上 script 脚本,可以在任意模块内通过 process.env.NODE_ENV 获取当前的环境变量

但无法在 node 环境(webpack 配置文件中)下获取当前的环境变量

// index.js
function getEnv() {
 console.log(process.env.NODE_ENV);// development | production
}

// webpack.config.js
const path = require('path');
const webpack = require('webpack');

console.log('NODE_ENV',process.env.NODE_ENV);// undefined

module.exports = {
 	entry:'./src/index.js',
  output: {
   filename: 'js/[name].js'
  },
 		...
};

2.1.2 写法二

"scripts": {
 "dev2": "webpack --mode=development",
 "build2": "webpack --mode=production",
}

和写法一, 是一样的结果

2.1.3 写法三

"scripts": {
 "dev3": "webpack-dev-server --env=development",
 "build3": "webpack --env=production",
}

以上 script 脚本,无法在任意模块内通过 process.env.NODE_ENV 获取当前的环境变量

但可以在 node 环境(webpack 配置文件中)下,通过函数获取当前环境变量

// index.js
function getEnv() {
 console.log(process.env.NODE_ENV);// undefined
}

// webpack.config.js
const path = require('path');
const webpack = require('webpack');

console.log('NODE_ENV',process.env.NODE_ENV);// undefined

// 通过函数获取当前环境变量
module.exports = (env,argv) => {
 console.log('env',env);// development | production
 return {
 	entry:'./src/index.js',
  output: {
   filename: 'js/[name].js'
  },
 		...
 }
};

2.2 使用 mode

// index.js
function getEnv() {
  console.log(process.env.NODE_ENV);// development | production
}

// webpack.config.js
const path = require('path');
const webpack = require('webpack');

console.log('NODE_ENV',process.env.NODE_ENV);// undefined

module.exports = {
 	mode:'development',// development | production
 	entry:'./src/index.js',
    output: {
      filename: 'js/[name].js'
    },
  		...
};

和 2.1 中的写法二,是一样的结果

一个是在命令行中设置,一个是在 webpack 配置文件中设置

2.3 使用 webpack.DefinePlugin

首先得知道这个插件的作用:设置全局变量(并非挂载到 window 上),所有模块都能读取到该变量的值

// index.js
function getEnv() {
  console.log(process.env.NODE_ENV);// development
  console.log(NODE_ENV);// production
}

// webpack.config.js
const path = require('path');
const webpack = require('webpack');

// 这里只是凑巧和环境变量同名了,所以才不会报错
console.log('process.env.NODE_ENV',process.env.NODE_ENV);// undefined
console.log('NODE_ENV',NODE_ENV);// error !!!

module.exports = {
 	mode:'development',// development | production
 	entry:'./src/index.js',
    output: {
      filename: 'js/[name].js'
    },
 	plugins:[
      new webpack.DefinePlugin({
      	'process.env.NODE_ENV':JSON.stringify('development'),
        'NODE_ENV':JSON.stringify('production'),
    }),
  ],
  		...
};

可以在任意模块内通过 process.env.NODE_ENV 获取当前的环境变量

但无法在 node 环境(webpack 配置文件中)下获取当前的环境变量

2.4 使用 cross-env 插件

原先我一直以为这个插件,可以用来设置所有环境(浏览器环境、node 环境)下的变量。经过测试发现,只能设置node 环境下的变量 —— NODE_ENV

2.4.1 写法一

"scripts": {
 	"dev1": "cross-env NODE_ENV='production' webpack-dev-server",
    "build1": "cross-env NODE_ENV='development' webpack",
}

以上 script 脚本,可以在任意模块内通过 process.env.NODE_ENV 获取当前的环境变量

可以在 node 环境(webpack 配置文件中)下,获取当前环境变量

但是会有一个问题: 浏览器环境和 node 环境下获取到的值是不一样的

// !!!!!!
// npm run build1
// !!!!!!

// index.js
function getEnv() {
  console.log(process.env.NODE_ENV);// production
}

// webpack.config.js
const path = require('path');
const webpack = require('webpack');

console.log('process.env.NODE_ENV',process.env.NODE_ENV);// development

module.exports = {
 	entry:'./src/index.js',
    output: {
      filename: 'js/[name].js'
    },
  		...
};

2.4.2 写法二

"scripts": {
 "dev2": "cross-env NODE_ENV='development' --mode development",
 "build2": "cross-env NODE_ENV='production' --mode production",
}

以上 script 脚本,可以在任意模块内通过 process.env.NODE_ENV 获取当前的环境变量

可以在 node 环境(webpack 配置文件中)下,获取当前环境变量

所以在能浏览器环境下读取到环境变量的值,靠的是 mode ,在 node 环境下读取到环境变量的值,靠的是 cross-env

// !!!!!!
// npm run build2
// !!!!!!

// index.js
function getEnv() {
  console.log(process.env.NODE_ENV);// production
}

// webpack.config.js
const path = require('path');
const webpack = require('webpack');

console.log('process.env.NODE_ENV',process.env.NODE_ENV);// production

module.exports = {
 	entry:'./src/index.js',
    output: {
      filename: 'js/[name].js'
    },
  		...
};

三、误区

经常在一些群里看到这个问题: cross-env 和 webpack.DefinePlugin 配合使用的时候,无法通过 process.env.xxx 来获取到设置的环境变量,需要通过 webpack.DefinePlugin 里面设置的 key 来获取。

会引发这个问题的可能原因是:先往 cross-env 里设置了 NODE_ENV 变量,然后又到 DefinePlugin里设置了一遍环境变量

"scripts": {
 "dev": "cross-env NODE_ENV='development' --mode development"
}
// index.js
function getEnv() {
  console.log(process.env.NODE_ENV);// development
}

// webpack.config.js
const path = require('path');
const webpack = require('webpack');

console.log('process.env.NODE_ENV',process.env.NODE_ENV);// development

module.exports = {
 	entry:'./src/index.js',
    output: {
      filename: 'js/[name].js'
    },
 	plugins:[
      new webpack.DefinePlugin({
       	// 设置环境变量
        	'process.env.NODE_ENV':JSON.stringify('development'),
      }),
    ],
  		...
};

此时会发现浏览器环境和 node 环境都能获取到设置的变量了,然后就认为之后再设置其他的全局变量时,也像这样写就行了。

认为 cross-env 和 DefinePlugin 是配套一起使用的,这个看法本身就很奇怪,因为两者的作用点不一样

  • DefinePlugin 的作用:是设置浏览器环境下能读取到的 "全局变量",直接通过 key 读取,在 node 环境下是无法读取到的
  • cross-env 的作用:是通过命令行设置环境变量 NODE_ENV,使 node 环境下能读取到,通过 process.env.NODE_ENV 读取
  • 如果在DefinePlugin 里设置的 key 是 process.env.NODE_ENV ,会覆盖 webpack 通过 mode 模式设置的环境变量的值
"scripts": {
 "dev": "cross-env NODE_ENV='development' --mode development"
}
// index.js
function getEnv() {
  console.log(process.env.NODE_ENV);// 666666
}

// webpack.config.js
const path = require('path');
const webpack = require('webpack');

console.log('process.env.NODE_ENV',process.env.NODE_ENV);// development

module.exports = {
 	entry:'./src/index.js',
    output: {
      filename: 'js/[name].js'
    },
 	plugins:[
      new webpack.DefinePlugin({
        // 注意:因为同名的 key,这里的值会覆盖默认的值 !!!!!!
        	'process.env.NODE_ENV':JSON.stringify('666666'),
      }),
    ],
  		...
};

四、总结

cross-env 是专门用来设置 node 环境变量的

webpack.DefinePlugin 是专门用来设置浏览器环境下的全局变量(不会挂载到 window 上)

本文只是我个人的理解,如有错误还请告知,万分感谢

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对我们的支持。

(0)

相关推荐

  • webpack本地开发环境无法用IP访问的解决方法

    问题描述: 只能用http://localhost:8080访问项目,不能用http://本机IP:8080访问 解决方案: webpack dev配置文件中加上 host:'0.0.0.0' 以上这篇webpack本地开发环境无法用IP访问的解决方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们. 您可能感兴趣的文章: 解决webpack无法通过IP地址访问localhost的问题

  • webpack vue项目开发环境局域网访问方法

    思路:将自己的项目启动ip与端口固定,当然端口也可以为默认的8080 步骤: 1.查看自己在局域网内的ip 命令行 ipconfig 2.回到自己的开发目录,在根目录找到comfig/index.js 修改 host: 自己的局域网ip 修改 port: 自定义端口-最好不要用80或者其他常用端口 示例:comfig/index.js host:'http://192.168.2.153',//一定要加上 http port:3000 注意:此处ip一旦固定,本机访问的或localhost将不可

  • 浅谈Webpack下多环境配置的思路

    前言 由于前后端分离的前端应用脱离了后端的支持,在单独开发前端应用时,页面调试时使用固定的开发环境地址还好,如果出现在本地开发时需要调试不同环境的远端API,或者需要将应用部署到不同环境的服务器上时,如果不将这些环境对应的服务器地址.环境专属变量等单独配置,也许每次切换环境都需要修改大量代码.网上关于这部分的资料较少,所以下面将以用vue-cli init命令生成的Vue/Webpack项目作为例子,介绍一下我当前正在使用的简单的多环境配置的思路. 1.理想中的多环境配置 在后端开发中,项目中不

  • react.js使用webpack搭配环境的入门教程

    本文介绍了react.js使用webpack搭配环境的入门教程,分享给大家,也给自己做个笔记 如果你想直接上手开发,而跳过这些搭配环境的繁琐过程,推荐你使用官方的create-react-app命令 npm install -g create-react-app //安装create-react-app脚手架 npm为node.js的包管理工具,请确保你已经安装了node.js create-react-app my-app //使用create-react-app创建,my-app为项目名称

  • 详解Webpack + ES6 最新环境搭建与配置

    一,准备工作 1.下载node.js 和 npm 2.将镜像源替换为淘宝镜像 二,创建目录及安装webpack创建项目 在命令行中输入 npm init -y 我们看到了项目中多了一个package.json文件,它定义了这个项目中所需各种模板及项目中的配置信息.该对象的每一个成员就是当前项目的一项设置.详细设置信息请参考 https://docs.npmjs.com/files/package.json 安装webpack 全局安装webpack,在命令行输入 npm install webp

  • 详解webpack+angular2开发环境搭建

    刚搭建完一个webpack+angular2环境,由于angular及webpack官网上没有一个折中的搭建方案,所以只能摸索着搭建,中间遇到一些坑,遂总结记录下来,以供交流. 搭建完后的项目初步环境如下: app ----app.component.ts ----app.module.ts ----main.ts index.html package.json tsconfig.json webpack.config.js app.componnet.ts:组件文件.angular2应用是由组

  • vue+node+webpack环境搭建教程

    一.环境搭建 1.1.去官网安装node.js(http://www.runoob.com/nodejs/nodejs-install-setup.html ) 注意node的版本,只有支持和谐模式的node才会支持es6,在基于webpack构建项目名称时才不会报错.推荐最新版本. 下载安装包之后直接点击安装即可.测试安装成功的界面如下: 1.2.利用npm安装webpack命令行语句为npm install webpack -g.测试安装成功的界面如下: 1.3.下面就是安装淘宝镜像,如下图

  • windows下vue-cli及webpack搭建安装环境

    1.安装Node.js,node.js安装包及源码下载地址为:https://nodejs.org/en/download/. 2.安装npm,由于新版的nodejs已经集成了npm,所以之前npm也一并安装好了.同样可以通过输入 "npm -v" 来测试是否成功安装.命令如下,出现版本提示表示安装成功: $ npm -v 3.10.8 如果你安装的是旧版本的 npm,可以很容易得通过 npm 命令来升级,命令如下: npm install npm -g 你可以使用淘宝定制的 cnpm

  • Webpack设置环境变量的一些误区详解

    一.前言 日常的前端开发工作中,至少会有两套构建环境 一套开发时使用,构建结果用于本地开发调试,不进行代码压缩.打印 debug 信息.包含 sourcemap 文件等 一套发布时使用,构建结果用于线上,即代码都是压缩过的.运行时不打印 debug 信息.静态文件不包括 sourcemap 等 webpack 4.0 版本开始引入了 mode 的概念 选项 描述 development 会将 process.env.NODE_ENV 的值设为 development.启用 NamedChunks

  • vue cli4下环境变量和模式示例详解

    本文介绍了vue cli4下环境变量和模式示例详解,分享给大家,具体如下: 官方文档 环境变量 一个环境变量文件只包含环境变量的键值对: NODE_ENV=development VUE_APP_BASE_URL=http://127.0.0.1:8080/ 注意: NODE_ENV - 是 "development"."production" ."test"或者自定义的值.具体的值取决于应用运行的模式 BASE_URL - 会和 vue.con

  • Nest.js环境变量配置与序列化详解

    环境变量配置简述 程序在不同的环境下需要不同的环境变量,例如生产环境.测试环境以及开发环境所需要不同的数据库信息:链接地址.链接端口号.登录用户名和密码相关信息.为了解决这个问题需要进行相关操作. 在 Nest 中最佳方案创建一个 ConfigModule,该 ConfigModule 公开一个 ConfigService ,在 ConfigService 加载特有环境的 .env 文件. Nest 提供了 @nestjs/config 开箱即用的依赖包. 配置 npm 生态有很多相关的依赖包,

  • Anaconda环境变量的配置图文详解

    目录 前言 一.什么是环境变量 二.环境变量的作用 三.步骤 四.小结 前言 此文记录了我在进行 Anaconda 环境变量配置的做法 ,希望可以对有需要的朋友们有所帮助或者启发 一.什么是环境变量 环境变量一般是指操作系统中用来指定操作系统的一些参数,如:临时文件夹位置和系统文件夹位置等. 环境变量是在操作系统中一个具有特定名字的对象,它包含了一个或多个应用程序所将使用到的信息.例如 Windows 和 DOS 操作系统中的 path 环境变量,当要求系统运行一个程序而没有告诉他程序所在的完整

  • dos 环境变量延迟扩展enabledelayedexpansion详解

    一,什么是延迟环境变量扩展? 延迟变量全称"延迟环境变量扩展",要理解这个东西,我们还得先理解一下什么叫变量扩展!   CMD在解释我们的命令的时候,首先会读取一条完整的命令,然后对其进行一些命令格式的匹配操作,看你所输入的 命令格式是不是符合它的要求.如果我们要在命令中引用一些变量,那么我们如何让CMD在解释我们的命令时,能识别 出这个变量呢?这时我们就可以在变量名字两边加一个%号,如%name%.当CMD在读取我们的整条命令进行格式匹配的时 候,就会发现name这个字符两边加了%号

  • python解释器pycharm安装及环境变量配置教程图文详解

    1.python解释器安装 下载地址:https://www.python.org/ 打开官网,点击downloads,选择操作系统,以windows为例: 选择python2与python3解释器版本(以python3.6.6及python2.7.16为例): 以python3.6.6为例,根据操作系统下载不同安装包(python2.7.16类似) 下载完成后,双击打开,选择自定义安装: 点击完成后,选择下一步,修改默认安装路径(方便查找,添加环境变量),完成后点击安装 2.配置环境变量 右击

  • Postman环境变量全局变量使用方法详解

    背景: [登录接口]中会返回sign值,[学生金币充值接口]会则需要用到该sign值,因此把sign设置为环境或全局变量,便于其他接口调用. 1.请求登录接口,获取sign值: 2.把sign值添加至环境变量或者全局变量,如下: (1)手动添加sign至环境变量: 并在[学生金币充值接口]调用该环境变量: (2)自动添加sign到环境变量: 在[登录接口]中使用Tests语句自动添加环境变量: 发送请求运行后,再次查看gold_cookie,已自动添加sign值: 现在可在[学生金币充值接口]中

  • Linux中环境变量配置的步骤详解

    简介 我们大家在平时使用Linux的时候,经常需要配置一些环境变量,这时候一般都是网上随便搜搜就有人介绍经验的.不过问题在于他们的方法各不相同,有人说配置在/etc/profile里,有人说配置在/etc/environment,有人说配置在~/.bash_profile里,有人说配置在~/.bashrc里,有人说配置在~/.bash_login里,还有人说配置在~/.profile里...这真是公说公有理...那么问题来了,Linux到底是怎么读取配置文件的呢,依据又是什么呢?下面这篇文章就来

  • Go获取与设置环境变量的方法详解

    目录 前言 01 从安装 Go 说起 02 Go 如何使用环境变量 03 小结 前言 今天的文章比较基础,但却是必须掌握的,而且本文有些内容,也许你之前没想过.希望这篇文章能够让你理解环境变量并掌握 Go 环境变量相关操作. 01 从安装 Go 说起 其实不止是安装 Go,其他语言一本也会有类似的问题.一般来说,安装完 Go 后,会建议将 go 可执行程序配置到 PATH 环境变量中. 比如我本地的 PATH 环境变量的值: $ echo $PATH /Users/xuxinhua/.go/bi

  • python设置环境变量的原因和方法

    相信很多初学python的小伙伴都会遇到这样的坑:环境变量配置不好,无法正常启动python.那么环境变量究竟是个什么东西呢?为什么要设置它?下面我们来说一说. 1.什么是环境变量 引用百度百科里面的解释:环境变量是在操作系统中一个具有特定名字的对象,它包含了一个或者多个应用程序所将使用到的信息.看到这里我相信大家可能还是有所疑惑,但是,不急,接着看. 2.为什么需要环境变量 windows系统下,假如我们安装了某一款软件,安装结束后,在安装目录会生成一个该软件的.exe文件,双击该文件,我们就

随机推荐