将Node Express配置为提供静态的bower_components文件?

71

我有一个目录结构

projectName
    | - bower_components/
    | - public/
        | - css
        | - js
        | - index.html
    | - Gruntfile.js
    | - package.json
    | - bower.json
    | - app.js

我想要使用node启动我的应用并提供index.html文件。因此,在app.js中,我有如下代码:

var express = require('express');
var port = process.env.PORT || 3000;
var app = express();

app.configure(function(){
    // Serve up content from public directory
    app.use(express.static(__dirname + '/public'));
    app.use(app.router);
    app.use(express.logger()); 
});

app.listen(port, function(){
    console.log('Express server listening on port ' + port);
});

我在index.html底部添加了以下内容:

<script src="../bower_components/jquery/jquery.js"></script>
<script src="../bower_components/d3/d3.js"></script>
<script src="../bower_components/bootstrap/dist/js/bootstrap.js"></script>
<script src="bower_components/spin.js/spin.js"></script>
<script src="bower_components/mustache/mustache.js"></script>

当我启动服务器时,index.html 文件会显示出来,但是上面的库都没有加载。我收到了一个错误(404):

启动服务器后,index.html 页面会显示,但上述的库并未加载,出现了404错误提示:

GET http://localhost:3000/bower_components/jquery/jquery.js 404 (Not Found) localhost/:32
GET http://localhost:3000/bower_components/d3/d3.js 404 (Not Found) localhost/:33
GET http://localhost:3000/bower_components/bootstrap/dist/js/bootstrap.js 404 (Not Found) localhost/:34
GET http://localhost:3000/bower_components/spin.js/spin.js 404 (Not Found) localhost/:35
GET http://localhost:3000/bower_components/mustache/mustache.js 404 (Not Found) 

我该如何提供来自bower_components的文件?


请参考我的类似问题(已回答),也许可以帮到你:https://dev59.com/fYDba4cB1Zd3GeqPASXc - Green
我有一个问题。package.jsonbower.json是否会相互冲突?例如对于名称、版本甚至是同一包的不同版本的依赖项等字段,你应该将它们放在package.json还是bower.json中呢? - Nam Thai
package.json 用于 npm 依赖 (通常是服务器端或构建系统的要求),而 bower.json 则仅用于客户端依赖,例如 bootstrap、angular 或 jquery。它们彼此不冲突。 - Connor Leech
7个回答

194

我使用这个设置:

app.use(express.static(__dirname + '/public'));
app.use('/bower_components',  express.static(__dirname + '/bower_components'));

所以任何 Bower 组件可以像这样从 HTML 中加载:

<script src="/bower_components/..."></script>

任何其他客户端 JS/CSS(在public/中)都是这样加载的:

<script src="/js/..."></script>

12
答案现在应该使用path.join(__dirname, '/bower_components')。 - Warren
我使用Yeoman生成Bootstrap和Express。我不得不将app.use('/bower_components', express.static(config.root + '/bower_components'));添加到/config/express.js文件中。请注意config.root而不是__dirname。 - kingdango
我有一个问题。上述项目同时有 package.jsonbower.json。它们会相互冲突吗?例如在名称、版本以及可能是不同版本的相同软件包的依赖项等字段中,应该将这些内容放在 package.json 还是 bower.json 中? - Nam Thai
一般来说,bower.json 用于客户端依赖,package.json 用于服务器端依赖。 - robertklep
path.join(__dirname, 'bower_components') 不需要第一个斜杠。你使用 path 库,所以它会使用系统的路径分隔符。 - Mustafa
显示剩余7条评论

8

您应该使用

app.use(express.static(path.join(__dirname, '/public')));
app.use('/bower_components',  express.static( path.join(__dirname, '/bower_components')));

请注意使用(path.join),这与@robertklep的答案不同。
以下是来自另一个SO问题的注释,我认为它很好地解释了这个问题。 path.join将处理不必要的分隔符,这些分隔符可能来自未知来源(例如用户输入、第三方API等)。
因此,path.join('a/','b') path.join('a/','/b'), path.join('a','b')和path.join('a','/b')都将给出a/b。
如果不使用它,你通常会对路径的开头和结尾作出预期,知道它们只有零或一个斜杠。

1
path.join 不应该使用 + 运算符进行字符串拼接,而应该使用逗号 , - Warlock
我已经尝试了+和, 但在Windows系统上无法工作。但是我能够使用同样的过程从其他文件夹中使用资产文件,只有"bower_components"文件夹无法工作。请帮我修复它。 - Sach
@robertklep 为什么我们需要对 bower_components 这样的目录进行操作,而不是像 css、js、img 这样的其他目录?我找不到任何文档。 - TSR

6

Bower可以使用JSON在.bowerrc文件中进行配置。

在项目根目录下添加一个.bowerrc文件,并使用以下内容。

{
  "directory": "public/bower_components"
}

这将把你引用的Bower组件放置在正确的库中,你将不需要在Express中提取静态目录。

1
将您的目录结构更改为:

projectName

    | - public/
        | - bower_components/
        | - css
        | - js
        | - index.html
    | - Gruntfile.js
    | - package.json
    | - bower.json
    | - app.js

index.html中进行以下更改:
<script src="../public/bower_components/jquery/jquery.js"></script>
<script src="../public/bower_components/d3/d3.js"></script>
<script src="../public/bower_components/bootstrap/dist/js/bootstrap.js"></script>
<script src="public/bower_components/spin.js/spin.js"></script>
<script src="public/bower_components/mustache/mustache.js"></script>


另一种方法是将您的bower_components文件夹转换为静态内容。(您可以多次为express注入static middleware
在应用程序配置中添加以下内容以使用express。然后您的配置代码如下:

var express = require('express');
var port = process.env.PORT || 3000;
var app = express();

app.configure(function(){
    // Serve up content from public directory
    app.use(express.static(__dirname + '/public'));
    app.use(express.static(__dirname + '/bower_components'));
    app.use(app.router);
    app.use(express.logger()); 
});

app.listen(port, function(){
    console.log('Express server listening on port ' + port);
});

在这种情况下,您的目录结构保持不变。希望这能帮到您。
祝编程愉快.. :)

2
我的直觉告诉我,这个被 down-vote 的原因是因为如果你手动将 bower_components 目录移动到另一个目录下,你会失去一些包管理器的功能。 - webkenny
2
您可以使用.bowerrc文件将bower配置为将其bower_components文件夹放在public文件夹中,例如此处的express和grunt示例。如果我正在使用Grunt,则希望在我的Gruntfile中配置服务器的静态文件目录,但我无法使用我正在使用的grunt-express找出如何执行它。因此,我的解决方案是只需移动文件夹即可。 - Matthias
1
我差点出于本能反对了你的回答。我一开始认为移动 bower_components 文件夹是一个反模式。但我想不出任何好的理由反对它,而且它看起来是一个简单的解决方案。 - Matthias

0

将 bower_components 移动到另一个文件夹后,我遇到了同样的问题。这让我明白了发生了什么。 文档很有帮助: https://github.com/expressjs/serve-static

然后 我将此代码放入我的 node/express app.js 文件中:

console.log('DIRNAME:', __dirname, 'JOINED:', path.join(__dirname, '../../bower_components'));

这是来自index.html的内容

<script src="/bower_components/jquery/dist/jquery.js"></script>
<script src="/bower_components/angular/angular.js"></script>

并且在 app.js 中

app.use('/bower_components', express.static(path.join(__dirname, '../../bower_components')))

在我的情况下,这是正确的路径。


0

这对我也有效:

app.use('/bower_components',  express.static(__dirname + '/bower_components'));

确保您已重置本地服务器或确保正在运行nodemon以查看更改!


0

我正在使用:

$ npm -version && node -v
2.11.3
v0.12.7

我的app.js文件定义了bower_components作为静态路径:

app.use(express.static(path.join(__dirname, 'bower_components')));

在我的Jade模板中,我这样引用jquerybootstrap:
doctype html
html
    head
        title= title
        link(href='bootstrap/dist/css/bootstrap.min.css', rel='stylesheet')
        link(href='bootstrap/dist/css/bootstrap-theme.min.css', rel='stylesheet')
    body
        block content

    script(type='text/javascript', src='jquery/dist/jquery.js')
    script(type='text/javascript', src='bootstrap/dist/js/bootstrap.js')

我正在运行 Windows 7 (x64)。

希望这能帮助到某些人。


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