美文网首页
webpack.DefinePlugin与cross-env区别

webpack.DefinePlugin与cross-env区别

作者: 涅槃快乐是金 | 来源:发表于2023-02-10 21:54 被阅读0次

    DefinePlugin 用来做定义,这就类似于我们项目开发中的config文件一样,在config文件中一般放的是系统代码中的一些服务器地址之类的公共信息,我们将这些信息提取出来单独放在配置文件中,方便于后期的维护和管理。

    那 DefinePlugin 的功能和 config 这个文件类似,我们可以在它里面定义一些公有信息,然后在代码里直接使用。

    一、DefinePlugin

    先来看看在Webpack的官方定义:

    DefinePlugin 允许创建一个在编译时可以配置的全局常量。这可能会对开发模式和生产模式的构建允许不同的行为非常有用。如果在开发构建中,而不在发布构建中执行日志记录,则可以使用全局常量来决定是否记录日志。这就是 DefinePlugin 的用处,设置它,就可以忘记开发环境和生产环境构建的规则。

    1、用法

    每个传进 DefinePlugin 的键值都是一个标志符或者多个用 . 连接起来的标志符。

    (1)如果这个值是一个字符串,它会被当作一个代码片段来使用。

    (2)如果这个值不是字符串,它会被转化为字符串(包括函数)。

    (3)如果这个值是一个对象,它所有的 key 会被同样的方式定义。

    (4)如果在一个 key 前面加了 typeof,它会被定义为 typeof 调用。

    这些值会被内联进那些允许传一个代码压缩参数的代码中,从而减少冗余的条件判断。

    new webpack.DefinePlugin({
      PRODUCTION: JSON.stringify(true),
      VERSION: JSON.stringify('5fa3b9'),
      BROWSER_SUPPORTS_HTML5: true,
      TWO: '1+1', 'typeof window': JSON.stringify('object'), 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV)
    });
    
    console.log('Running App version ' + VERSION); if(!BROWSER_SUPPORTS_HTML5) require('html5shiv');
    

    注意,因为这个插件直接执行文本替换,给定的值必须包含字符串本身内的实际引号。通常,有两种方式来达到这个效果,使用 '"production"', 或者使用 JSON.stringify('production')

    2、官网中说的:“可以使用这个插件定义一些编译时的全局常量”

    编译时这几个字很重要,webpack会根据配置文件将将入口文件解析、打包、转译为浏览器可识别的js文件最后输出到出口,而他转译的过程其实就是webpack编译过程,也就是官网说的编译时。

    3、官网中说的:“插件会直接替换文本”

    在编译过程中(转译为浏览器可识别的js文件时),会将源文件中所有用到DefinePlugin中定义的常量的地方直接替换为对应的值文本,注意,是文本无论语义上是对象还是字符串还是函数,都直接作为文本替换过去。

    4、示例使用

    //1、假设在配置文件中定义编译时全局常量 process.env.firstName
    new webpack.DefinePlugin({ 'process.env.firstName': JSON.stringify("Test")
    }); //源文件index.js内容如下
    console.log(process.env.firstName) //最终转译后的js文件
    console.log('Test')
    

    可以看到,在编译生成新js文件时,将process.env.firstName常量直接替换成了他对应的值文本

    //2、假设在配置文件中定义编译时全局常量 process.env.info
    new webpack.DefinePlugin({ 'process.env.info': JSON.stringify({
            ame:'Test',
            age:23 })
    }); //源文件index.js内容如下
    console.log(process.env);
    console.log(process.env.info) //最终转译后的js文件
    console.log(process.env);
    console.log({
        name:'Test',
        age:23 })
    

    可以看到,在编译生成新js文件时,将process.env.info常量直接替换成了他对应的值文本,而process.env没有被替换,因为没有在DefinePlugin中定义process.env

    运行最终转译后的js文件时,process.env指向的是Node中的process,在process.env中找不到info属性,足以证明在DefinePlugin定义的process.env.info和Node的process没有任何关系,他只是一个在插件中定义的编译时的常量,编译后就已经被替换了。

    因此理解清楚概念,他只是个编译时的常量,转译后就会被替换,只是恰好常量的名字是process.env.info。

    二、webpack.DefinePlugin与cross-env区别详解

    webpack.DefinePlugin与cross-env常用于在项目工程化中定义环境变量:

    1、webpack.DefinePlugin 用于在编译期定义环境变量,意味着在代码中写上 process.env.NODE_ENV 不会在编译期出现错误提醒;

    2、cross-env 库用于在运行时定义环境变量

    3、问题场景:为什么要使用 cross-env 库?

    在进行“NODE_ENV=development webpack”配置时候,在大多数Windows命令行中在使用NODE_ENV = production设置环境变量时会报错。同样Windows和Linux命令如何设置环境变量也有所不同。所以需要使用 cross-env 库来支持跨平台设置和使用环境变量的脚本,这样可以设置在不同的平台上有相同的NODE_ENV参数

    4、DefinePlugin 用途:

    根据不同的环境进行不同的配置,如不同环境的域名不同,我们就可以利用 DefinePlugin(https://www.webpackjs.com/plugins/define-plugin/)进行配置

    // config/env.js 配置文件
    const env = process.env.NODE_ENV; const config = {
      development: {
        loginApi: 'www.abc-login-test.com',
        orderApi: 'www.abc-order-test.com' },
      production: {
        loginApi: 'www.abc-login.com',
        orderApi: 'www.abc-order.com' }
    };
    module.exports = config[env]; // webpack.config.js
    const envConfig= require('./config/env');
    module.exports = {
      plugins: [ new webpack.DefinePlugin({
          envConfig: JSON.stringify(envConfig)
        })
      ]
    } // 这样就可以使用不同的结果
    

    相关文章

      网友评论

          本文标题:webpack.DefinePlugin与cross-env区别

          本文链接:https://www.haomeiwen.com/subject/ptflkdtx.html