使用Browserify时出现require未定义的错误

37

我刚开始接触browserify,尝试在浏览器中加载npm模块,但是出现了以下错误:

Uncaught ReferenceError: require is not defined

我按照http://browserify.org/上的教程进行操作。创建了一个包含以下内容的javascript文件:

var unique = require('uniq');

然后运行

npm install uniq

以及

browserify main.js -o bundle.js

生成了bundle.js文件,并将其加入我的html文件中,但仍然出现上述错误。你有任何想法我做错了什么吗?

以下是最终HTML文件的内容:

<!DOCTYPE html>
<html>
<head>
    <title></title>

    <script src="bundle.js"></script>
    <script src="script.js"></script>
</head>
<body>

</body>
</html>

这是bundle.js的内容:http://pastebin.com/1ECkBceB

而这是script.js:

var unique = require('uniq');


你能贴更多的代码以提供上下文吗?bundle.js和script.js的内容是什么? - sma
@sma 刚刚更新了问题,包括两个文件的内容。 - King Julien
4个回答

41

"require"函数仅在"bundle.js"脚本上下文中可用。Browserify会获取所有必要的脚本文件并将它们放入"bundle.js"文件中,因此您只需要在HTML文件中包含"bundle.js"而不是"script.js"文件。


3
那么我不能要求为该目的捆绑在一起的模块吗? - eran otzap
1
在运行browserify之前,您可以在编写的源代码中使用“require”。因此,在您的源JavaScript中,您可以要求任何需要的模块,然后当您对源进行browserify时,它将打包所有源(包括您所需的模块)到“bundle.js”文件中,您可以在html中引用它。希望这有所帮助! - kevinvile
4
我现在明白了——browserify无法创建一个可以从浏览器中require()的模块——它会将你的代码打包并将整个内容包装在一个闭包中——你需要特殊的步骤才能创建一个可以在浏览器中使用的库。我会找出这些步骤,并将它们添加到这个答案中,因为很多人都会像提问者和我一样犯同样的误解。 - speciesUnknown

15

我个人更喜欢将我的库代码和应用程序代码分开。因此,我还会创建类似于 bundle.jsscript.js 的东西。

有一个简单的解决方法可以使这个工作正常。这是在我的 Browserify 文件中的某个地方:

window.require = require;

这将把require暴露到“全局”命名空间中。然后,您可以从script.js中要求所有您想要的内容。

然而,您需要放弃一个优势:您必须在您的browserify文件中包含所有所需的库。它不会自动查找并加入所有依赖项!

我完全希望人们会哭着说“肮脏的黑客技巧”或“这不是正确的用法”。是的,也许。但我想要这些文件分离。只要我不包括任何其他被称为“require”的东西,我就没问题了,非常感谢。

有时候,一个全局变量可以改变一切。


11

看起来你需要在捆绑包上使用独立模式才能运行这样的脚本。

browserify main.js --standalone Bundle > bundle.js

之后,你应该在 bundle.js 文件中拥有 window.Bundle。这样,在那个时刻,你就能够从 script.js 访问它。

如果你正在使用 grunt

如果你正在使用 grunt,请安装 grunt-browserify

npm install grunt-browserify --save-dev

然后在 grunt.js Gruntfile 文件中:

// Add the task
grunt.loadNpmTasks('grunt-browserify');

// Add the configuration:
browserify: {
    dist: {
        options: {
            // uncomment if you use babel
            // transform: [
            //     ["babelify", { "presets": ["env"] }]
            // ],
            browserifyOptions: {
                standalone: 'Bundle'
            }
        },
        files: {
           "bundle.js": ["main.js"]
        }
    }
},

如果你正在使用gulp

 // on your build task
 var bundled = browserify('main.js', { standalone: 'Bundle' })
               .bundle()
               .pipe(source('bundle.js'))
               .pipe(gulp.dest(outDir));

查看此处 Chart.js 的 gulp 文件。

如果您正在使用 babel

如果您正在使用 babel 并且使用了 es6,那么您可能正在导出您的 Bundle 类。

// you should have something like that 

class Bundle {
    ...

}

export default Bundle;

因为Babel的缘故,现在使用Bundle时应该使用Bundle.default,即:

// in script.js
var bundle = new Bundle.default();
为了避免这种语法,您可以使用 Bundle.default 覆盖 Bundle
在 bundle.js 的末尾插入:
window.Bundle = window.Bundle.default;

从现在开始你将拥有:

// in script.js
var bundle = new Bundle();

来源

独立的 browserify 构建


1
现在你会得到一个新的 Bundle.default(),这与几段之前没有任何区别,关于 Babel 和 Bundle.default() 的结尾部分并没有意义。 - joedotnot
谢谢 @joedotnot 修复。你推断的覆盖的主要目的是有 var bundle = new Bundle(); - borracciaBlu

9

简短回答:移除导入。

详细解释:你遇到了这个错误,是因为浏览器中未定义require方法。所以不应该包含script.js文件。

Browserify 的思路是:可以使用 CommonJS 模块拆分源代码,并将它们捆绑成一个文件用于在浏览器中使用。Browserify 将遍历所有源代码,并将所有运行require的文件都连接到一起形成一个捆绑文件。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接