最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 项目中如何区分环境和设置环境变量

    正文概述 掘金(柒柒是个小可爱)   2021-03-14   814

    构建环境和运行环境

    构建环境

    • 开发环境:我们正在开发的这个阶段所处的环境,也就是方便我们开发人员调试开发的一种环境构建,结果用于本地开发调试,不进行代码压缩、打印 debug 信息、包含 sourcemap 文件等。
    • 生产环境|线上环境:我们将程序开发完成经过测试之后无明显异常准备发布上线的环境构建,也可以理解为用户可以正常使用的就是生产环境。构建结果用于线上,即代码都是压缩过的、运行时不打印 debug 信息、静态文件不包括 sourcemap、通过tree-shaking去除开发环境特有代码等。

    部署和部署环境

    • 部署:简单的来说部署指的就是将构建后的代码放到服务器上去,这个服务器可以是本地的也可以是远程的,所以相应地部署就分为远程部署和本地部署。
    • 部署环境|运行环境:一个软件产品从开发到用户可能经过一系列流程,开发->测试->上线,所以相应的环境也可以分为开发环境、测试环境、预发布环境、生产环境等。

    构建环境和部署环境的关系

    • 构建环境是从代码打包层面上区分的,部署环境是从代码的运行层面上区分的
    • 不同的运行环境依赖于其对应构建环境打包出来的产物
    • 运行环境和构建环境并不是一一对应的,比如生产环境也可以运行开发环境打包出来的产物,但是实际上为了用户体验和方便测试,运行环境的生产、测试、预发布环境对应的是构建环境中的生产环境。
    • 对于最终运行在浏览器中的代码,构建过程是发生在node环境中的,运行是在浏览器环境中的,这里也会有一些差异。

    如何区分环境以及设置环境变量

    webpack中如何判断构建环境

    客户端代码中的判断

    • 我们经常能看到前端利用 process.env.NODE_ENV 来判断当前处于什么构建环境,但其实process是node中独有的对象,实际上在前端运行环境或者window上中并没有process相关信息。

    • 那么如何在前端判断当前环境呢?有时候我们看到前端环境也在使用process.env.NODE_ENV来判断环境?那又是怎么做到的尼?

    在webpack打包中,提供 mode 选项来配置构建环境

    选项描述
    development会将 DefinePlugin 中 process.env.NODE_ENV 的值设置为 development. 为模块和 chunk 启用有效的名。production会将 DefinePlugin 中 process.env.NODE_ENV 的值设置为 production。为模块和 chunk 启用确定性的混淆名称,FlagDependencyUsagePlugin,FlagIncludedChunksPlugin,ModuleConcatenationPlugin,NoEmitOnErrorsPlugin 和 TerserPlugin 。

    设置了mode后,webpack将通过 webpack.DefinePlugin 插件将环境配置成对应的值。类似于下面这样:

    plugins: [
        new webpack.DefinePlugin({
            "process.env": {
                NODE_ENV: JSON.stringify(mode),
             },
        })
    ]
    

    这里的 process.env.NODE_ENV 跟node环境的 process.env.NODE_ENV 并不是一回事,是在编译代码前的字符串分析时候遇到 'process.env.NODE_ENV' 这个字符串时,将该字符串替换为设置的值,所以在设置值的时候需要执行一下JSON.stringify函数。过程如下:

    let sourceCode = `console.log(process.env.NODE_ENV)`
    sourceCode.replace('process.env.NODE_ENV', JSON.stringify('development'))
    
    // 结果如下
    resultCoude = `console.log('development')`
    
    // 不添加 JOSN.stringify, 执行的时候会找不到 development 而报错
    resultCoude = `console.log(development)`
    

    其本质是字符串的替换,而不是添加了 process 这个全局数据。因此window下是没有挂process 这个字段的,包括 process.env['NODE_ENV']也是无法识别的。当然这里也可以用其他字符串,只要没有命名冲突都可。用process.env可能只是让看起来一致点?,同时不污染全局变量环境,也可以在process.env后面上挂在其他变量process.env.BASE_URL等。

    node端判断环境

    // webpack.config.js
    console.log('process.env.NODE_ENV', process.env.NODE_ENV); // 1
    module.exports = {
      mode: "development",
      plugins: [
        // 设置 mode 后,webpack 会自动配置下面
        new webpack.DefinePlugin({
          "process.env": {
            NODE_ENV: JSON.stringify('development'),
          },
        }),
      ],
    };
    
    // index.js
    console.log('process.env.NODE_ENV', process.env.NODE_ENV); // 2
    

    运行结果 1: undefined 2: 'development'

    出现的原因是因为 webpack.config.js 是运行在node环境,index.js是客户端运行,DefinePlugin只负责客户端的替换,而并没有给process.env.NODE_ENV赋值。process.env 本身也是不包含NODE_ENV这个变量的,也是需要开发者赋值的,那么如何设置值尼?

    项目中如何区分环境和设置环境变量

    答案就是通过cross-env设置环境变量

    // package.json
    {
        script: {
            // node 环境中 precess.env.NODE_ENV = development
            build1: 'cross-env NODE_ENV=development webpack xxx',
            
            // precess.env = {...precess.env, NODE_ENV: 'development', BASE_URL='api.xxx' }
            build2: 'cross-env NODE_ENV=development BASE_URL=api.xxx webpackxxx'
            
            // 同时配置构建环境和node环境
            "build3": "cross-env NODE_ENV='development' --mode development webpack xxx",
        }
    }
    

    当我们执行 npm run build3 后,上述的运行结果变为 1: 'development' 2: 'development',两端的环境判断以及获取就一致了。

    如何判断运行环境

    通过webpack控制

    1. 继续使用 mode 模式,设置node端环境,修改默认DefinePlugin
    // webpack.config.js
    // node 环境参数判断,node环境(构建环境)不需要感知 pre
    const getEnvInNode = () => {
        return process.env.NODE_ENV === 'development' ? 'development' : 'production'
    }
    console.log('process.env.NODE_ENV', process.env.NODE_ENV); // pre
    console.log(getEnvInNode()) // production
    module.exports = {
      mode: "development",
      plugins: [
        // 覆盖 mode 默认配置,传递环境给客户端
        new webpack.DefinePlugin({
          "process.env": {
            NODE_ENV: JSON.stringify(process.env.NODE_ENV),
          },
        }),
      ],
    };
    
    // package.js
    {
        script: {
            build: 'cross_env NODE_ENV=pre webpack'
        }
    }
    
    // index.js
    console.log('当前运行环境', process.env.NODE_ENV) // pre
    

    2、放弃使用 mode,自定义各种配置

    // webpack.pre.config.js
    console.log('process.env.NODE_ENV', process.env.NODE_ENV); // development | production 
    module.exports = {
      // 自定义配置 
      mode: "node",
      plugins: [
        // 不使用 mode 默认配置,传递环境给客户端
        new webpack.DefinePlugin({
          "process.env": {
            NODE_ENV: JSON.stringify('pre' | 'development' | 'production'),
          },
        }),
      ],
    };
    
    // package.js
    {
        script: {
            build:dev: 'cross_env NODE_ENV=development webpack --config ./webpack.development.config.js',
            build:pre: 'cross_env NODE_ENV=production webpack --config ./webpack.pre.config.js'
            build:prod: 'cross_env NODE_ENV=production webpack --config ./webpack.production.config.js'
        }
    }
    
    // index.js
    console.log('当前运行环境', process.env.NODE_ENV) // pre | development | production
    

    3、根据运行环境域名控制

    const domainHost = {
        'test.xxx.com': 'DEV',
        'pre.xxx.com': 'PRE',
        'xxx.com': 'PROD'
    }
    const env = domainHost[location.host] || 'DEV'
    

    在react、Vue中设置环境变量

    • vue: cli.vuejs.org/zh/guide/mo…
    • react: create-react-app.dev/docs/adding…
    • dotenv: github.com/motdotla/do…

    起源地下载网 » 项目中如何区分环境和设置环境变量

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元