【问题标题】:browserify - exclude code blocks?browserify - 排除代码块?
【发布时间】:2015-08-07 03:55:30
【问题描述】:

我正在使用浏览器和服务器端节点中的共享 React 组件构建一个应用程序。

现在,我正在使用 Marty.js 来执行此操作:

function getUser() {
    if (Marty.isBrowser) {
        /* Get user using some client method */  
    } else {
        /* otherwise, use some secret server code */
    }
}

我通过 Browserify 将这些功能捆绑在一起,因此它们可以在客户端和服务器上运行。

我想做的是从包中完全删除 else 块,这样我就不会泄露敏感的服务器端代码。

有没有办法从包中排除代码块?

【问题讨论】:

    标签: javascript node.js reactjs browserify


    【解决方案1】:

    我会创建单独的模块,一个用于浏览器,一个用于服务器。然后在 package.json 中,告诉 browserify 使用浏览器模块:

    "browser": {
        "./path/to/node-module.js": "./path/to/browser-module.js"
    }
    

    现在,无论你在哪里调用 require('path/to/node-module'),browserify 都会加载另一个模块。


    更多信息来自docs

    浏览器字段

    您可以在 package.json 中为每个模块设置一个特殊的“浏览器”字段,以覆盖特定于浏览器版本的文件的文件解析。

    例如,如果您想为“main”字段设置一个特定于浏览器的模块入口点,您可以将“browser”字段设置为字符串:

    "browser": "./browser.js"
    

    或者您可以基于每个文件进行覆盖:

    "browser": {
      "fs": "level-fs",
      "./lib/ops.js": "./browser/opts.js"
    }
    

    请注意,浏览器字段仅适用于本地模块中的文件,并且与转换一样,它不适用于 node_modules 目录。

    【讨论】:

      【解决方案2】:

      如何将代码放入模块中,例如UserServer,然后在为客户端编译时排除该模块?你的代码变成:

      function getUser() {
          if (Marty.isBrowser) {
              /* Get user using some client method */  
          } else { 
             require('UserServer').getUser();
          }
      }
      

      Browserify 提供以下选项来从包中排除文件:

      --exclude, -u  Omit a file from the output bundle. Files can be globs.
      

      【讨论】:

        【解决方案3】:

        更明确地说明您的意图,并将您的代码放在他们自己的文件中:

        function getUser(options, callback) {
          var fn;
          if (Marty.isBrowser) {
              fn = require("./lib/users/get.browser");
          } else {
              fn = require("./lib/users/get.server");
          }
          fn(options, callback);
        }
        

        然后作为 browserify 选项,你可以说“用这个变量替换 require("./lib/users/get.server"),当你看到它时:...”这样你在为浏览器构建时就不会在那个服务器文件中构建。

        但是,如果 getUser 可以根据运行的位置执行不同的操作,那么您在这里做错的可能性就更大了:也许 getUser 应该是从浏览器到您的服务器的 REST 调用,但没有更多信息,总是很难确定。

        【讨论】:

        • 在浏览器中,这是一个 REST 调用。在 Node 中,这是一个本地数据库调用。这是相同的后端 API,有两个不同的入口点(在浏览器中,首先检查会话和其他各种东西。)关键是能够生成初始渲染的 SSR 视图(不管 URL ) 并将其与来自浏览器的所有后续调用一起返回给浏览器。
        【解决方案4】:

        虽然我不确定 Browserify 是否可行,但您可以使用 Webpack 使用它的 DefinePlugin 来做到这一点

        来自docs(稍作修改):

        例子:

        new webpack.DefinePlugin({
            DEBUG: false,
            PRODUCTION: true,
            ...
        })
        

        ...

        例子:

        if(DEBUG)
            console.log('Debug info')
        if(PRODUCTION)
            console.log('Production log')
        

        通过 webpack 后没有缩小结果:

        if(false)
            console.log('Debug info')
        if(true)
            console.log('Production log')
        

        然后在缩小传递后:

        console.log('Production log')
        

        【讨论】:

        • 优秀的答案。您的 webpack 配置很可能已经使用 DefinePlugin 来设置 'process.env.NODE_ENV' 设置。
        【解决方案5】:

        您可以使用环境变量envifyuglify 来执行此操作。

        if ('browser' === process.env.ENVIRONMENT) {
          ...
        }
        else {
          ...
        }
        

        在构建浏览器时设置process.env.ENVIRONMENT = 'browser',使用envify 转换将process.env 的引用替换为其当前值,然后uglify 将执行死代码消除以删除永远不会被命中的分支。

        【讨论】:

        • +1 提示消除死代码 - 我不知道 uglify 这样做了。当然,这一步只假设缩小代码......在我的开发环境中,我使用完整的源代码 + 源映射,这仍然会暴露功能。
        猜你喜欢
        • 2014-11-08
        • 2016-10-15
        • 2019-01-05
        • 1970-01-01
        • 2018-05-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多