使用 webpack 在浏览器中使用 require 模块

Posted

技术标签:

【中文标题】使用 webpack 在浏览器中使用 require 模块【英文标题】:Using webpack to use require modules in browser 【发布时间】:2017-03-05 13:45:21 【问题描述】:

过去 2 天尝试在带有 webpack 的浏览器中使用 require('modules') 时,我可以在 5 分钟内在 browserify 中做同样的事情......

这是我的 webpack.config.js

var webpack = require('webpack');
var path = require('path');
var fs = require('fs');

var nodeModules = ;
fs.readdirSync('node_modules')
  .filter(function(x) 
    return ['.bin'].indexOf(x) === -1;
  )
  .forEach(function(mod) 
    nodeModules[mod] = 'commonjs ' + mod;
  );

module.exports = 
    entry: "./main.js",
    output: 
        filename: "bundle.js"
    

但是,无论我做什么,我都会遇到某种错误。目前我得到:

bundle.js:390 Uncaught Error: Cannot find module "net"

当我运行 webpack 时,它会抛出以下错误:http://pastebin.com/RgFN3uYm

我关注了https://webpack.github.io/docs/tutorials/getting-started/ 和http://www.pauleveritt.org/articles/pylyglot/webpack/,但我仍然收到这些错误。

我试过用这个来运行它:webpack ./main.js -o bundle.js 但它仍然不起作用。

如何解决?

【问题讨论】:

通过阅读node_modules 目录,您想在webpack.config.js 中完成什么?我以前从未见过有人这样做,而且您似乎没有将结果用于任何事情。 现在是无关代码。我不知道。很好,你标记了。 那我应该怎么做呢? 尝试在您的output 对象中包含path: __dirname(就像他们在“配置文件”here 部分中所做的那样)。我还将删除其他代码,以便您可以将其排除为问题的根源。 不幸的是,它仍然抛出同样的错误,虽然:( 【参考方案1】:

你应该添加目录来解析例如

 resolve: 
        modulesDirectories: ['./app/', './node_modules']
 

更新: 添加json加载器

npm install --save-dev json-loader

module: 
    loaders: [
       test: /\.json$/, loader: 'json-loader' 
    ]
  

fs、net、tls 也是 node.js 的库,不适用于浏览器内使用。您应该添加:

node: 
    fs: 'empty',
    net: 'empty',
    tls: 'empty'
  

【讨论】:

【参考方案2】:

你的文件夹结构是什么?

你应该有:

packages.json
node_modules/net/
webpack.config.js
src/main.js

然后在 main.js 上添加

var net = require('net');

在 webpack.config.js 上:

const path = require('path');

const PATHS = 
    src: path.join(__dirname, 'src'),
    dist: path.join(__dirname, 'dist')
;

module.exports = 
    entry: path.join(PATHS.src, 'main.js'),
    output: 
        path: PATHS.dist,
        filename: 'bundle.js'
    

运行webpack,这很重要,在 index.html 上,指向 bundle 文件,而不是 main.js!

【讨论】:

【参考方案3】:

无法从浏览器运行节点模块。

遗憾的是,就这么简单。让我们退后一步。来自official website:

Node.js® 是基于 Chrome 的 V8 javascript 引擎构建的 JavaScript 运行时。

这看起来像是一个细节,但本身并不是浏览器中的 JavaScript 运行时。然而,作为一个 JavaScript 运行时,它可以解释和运行 JavaScript 代码,并增加了与我们在浏览器中可以做的不同的功能,例如 require() 函数。它是在 Node 中构建的,但不是在 V8 中构建的。

节点还允许编写模块。您可以在 C++ 中编写一个节点模块,对其进行编译并在 Node 上下文中导入它。这是一个令人难以置信的优势,因为它允许 javascript 访问较低级别的功能,这反过来又允许使用 javascript 编写服务器。

低级功能在浏览器中不可用。

让我们考虑一下:

const fs = require('fs');

如果在浏览器中运行,它甚至应该意味着什么?什么文件系统?我敢说,在任何情况下,我都不应该希望我咨询的任何随机网站都可以访问它运行的机器的文件系统。在服务器的情况下,在 Node 环境中,访问文件系统是必要的。

节点模块,例如 fs、tls 或 net,使用浏览器中没有等效的低级功能,无论是逻辑(“什么文件系统?”)或安全性(“不,你的 javascript 代码不应该是能够创建原始 tcp 连接") 原因。

【讨论】:

以上是关于使用 webpack 在浏览器中使用 require 模块的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Typescript 中使用 Webpack 'require' 和 'require.ensure'

为什么我的浏览器在使用webpack拆分节点模块后显示空白页面?

使用 Webpack 时努力删除 FOUC(无样式内容的 Flash)

React 使用webpack构建React项目

忽略 Webpack 中的特定 require()?

webpack里的.env文件找不到