node.js 如何包含位于 node_modules 文件夹内的脚本?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27464168/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to include scripts located inside the node_modules folder?
提问by Chris
I have a question concerning best practice for including node_modulesinto a HTML website.
我有一个关于包含node_modules到 HTML 网站的最佳实践的问题。
Imagine I have Bootstrap inside my node_modulesfolder. Now for the production version of the website, how would I include the Bootstrap script and CSS files located inside the node_modulesfolder? Does it make sense to leave Bootstrap inside that folder and do something like the following?
想象一下,我的node_modules文件夹中有 Bootstrap 。现在对于网站的生产版本,我将如何包含位于node_modules文件夹内的 Bootstrap 脚本和 CSS 文件?将 Bootstrap 留在该文件夹中并执行以下操作是否有意义?
<script src="./node_modules/bootstrap/dist/bootstrap.min.js"></script>
Or would I have to add rules to my gulp file which then copy those files into my dist folder? Or would it be best to let gulp somehow completely remove the local bootstrap from my HTML file and replace it with the CDN version?
或者我是否必须向我的 gulp 文件添加规则,然后将这些文件复制到我的 dist 文件夹中?或者最好让 gulp 以某种方式从我的 HTML 文件中完全删除本地引导程序并将其替换为 CDN 版本?
回答by jfriend00
Usually, you don't want to expose any of your internal paths for how your server is structured to the outside world. What you can is make a /scriptsstatic route in your server that fetches its files from whatever directory they happen to reside in. So, if your files are in "./node_modules/bootstrap/dist/". Then, the script tag in your pages just looks like this:
通常,您不想向外界公开任何有关服务器结构的内部路径。你可以做的是/scripts在你的服务器中创建一个静态路由,从它们碰巧驻留的任何目录中获取它的文件。所以,如果你的文件在"./node_modules/bootstrap/dist/". 然后,您页面中的脚本标记如下所示:
<script src="/scripts/bootstrap.min.js"></script>
If you were using express with nodejs, a static route is as simple as this:
如果你在 nodejs 中使用 express,静态路由就像这样简单:
app.use('/scripts', express.static(__dirname + '/node_modules/bootstrap/dist/'));
Then, any browser requests from /scripts/xxx.jswill automatically be fetched from your distdirectory at __dirname + /node_modules/bootstrap/dist/xxx.js.
然后,来自 的任何浏览器请求/scripts/xxx.js将自动从您的dist目录中获取__dirname + /node_modules/bootstrap/dist/xxx.js。
Note: Newer versions of NPM put more things at the top level, not nested so deep so if you are using a newer version of NPM, then the path names will be different than indicated in the OP's question and in the current answer. But, the concept is still the same. You find out where the files are physically located on your server drive and you make an app.use()with express.static()to make a pseudo-path to those files so you aren't exposing the actual server file system organization to the client.
注意:较新版本的 NPM 将更多内容放在顶层,而不是嵌套得太深,因此如果您使用较新版本的 NPM,则路径名将与 OP 问题和当前答案中指示的不同。但是,这个概念仍然是一样的。您可以找出文件在服务器驱动器上的物理位置,然后使用app.use()withexpress.static()为这些文件创建伪路径,这样就不会将实际的服务器文件系统组织暴露给客户端。
If you don't want to make a static route like this, then you're probably better off just copying the public scripts to a path that your web server does treat as /scriptsor whatever top level designation you want to use. Usually, you can make this copying part of your build/deployment process.
如果您不想创建这样的静态路由,那么您最好将公共脚本复制到您的 Web 服务器确实视为的路径/scripts或您想要使用的任何顶级名称。通常,您可以将此复制作为构建/部署过程的一部分。
If you want to make just one particular file public in a directory and not everything found in that directory with it, then you can manually create individual routes for each file rather than use express.static()such as:
如果您只想在目录中公开一个特定文件,而不是在该目录中找到的所有文件都公开,那么您可以为每个文件手动创建单独的路由,而不是使用express.static()例如:
<script src="/bootstrap.min.js"></script>
And the code to create a route for that
以及为此创建路线的代码
app.get('/bootstrap.min.js', function(req, res) {
res.sendFile(__dirname + '/node_modules/bootstrap/dist/bootstrap.min.js');
});
Or, if you want to still delineate routes for scripts with /scripts, you could do this:
或者,如果您仍想用 描绘脚本的路线/scripts,您可以这样做:
<script src="/scripts/bootstrap.min.js"></script>
And the code to create a route for that
以及为此创建路线的代码
app.get('/scripts/bootstrap.min.js', function(req, res) {
res.sendFile(__dirname + '/node_modules/bootstrap/dist/bootstrap.min.js');
});
回答by Alexander Egorov
I would use the path npm module and then do something like this:
我会使用路径 npm 模块,然后做这样的事情:
var path = require('path');
app.use('/scripts', express.static(path.join(__dirname, 'node_modules/bootstrap/dist')));
回答by Marcelo Lazaroni
As mentioned by jfriend00 you should not expose your server structure. You could copy your project dependency files to something like public/scripts. You can do this very easilywith dep-linkerlike this:
正如 jfriend00 所提到的,您不应该公开您的服务器结构。您可以将项目依赖文件复制到类似public/scripts. 您可以像这样使用dep-linker轻松完成此操作:
var DepLinker = require('dep-linker');
DepLinker.copyDependenciesTo('./public/scripts')
// Done
回答by Jesse
If you want a quick and easy solution(and you have gulp installed).
如果你想要一个快速简单的解决方案(并且你已经安装了 gulp)。
In my gulpfile.jsI run a simple copy paste task that puts any files I might need into ./public/modules/directory.
在我的gulpfile.js我运行一个简单的复制粘贴任务,将我可能需要的任何文件放入./public/modules/目录中。
gulp.task('modules', function() {
sources = [
'./node_modules/prismjs/prism.js',
'./node_modules/prismjs/themes/prism-dark.css',
]
gulp.src( sources ).pipe(gulp.dest('./public/modules/'));
});
gulp.task('copy-modules', ['modules']);
The downside to this is that it isn't automated. However, if all you need is a few scripts and styles copied over (and kept in a list), this should do the job.
这样做的缺点是它不是自动化的。但是,如果您只需要复制一些脚本和样式(并保存在列表中),这应该可以完成工作。
回答by Jake
The directory 'node_modules' may not be in current directory, so you should resolve the path dynamically.
目录“node_modules”可能不在当前目录中,因此您应该动态解析路径。
var bootstrap_dir = require.resolve('bootstrap')
.match(/.*\/node_modules\/[^/]+\//)[0];
app.use('/scripts', express.static(bootstrap_dir + 'dist/'));
回答by curtwphillips
I want to update this question with an easier solution. Create a symbolic link to node_modules.
我想用更简单的解决方案更新这个问题。创建指向 node_modules 的符号链接。
The easiest way to grant public access to node_modules is to create a symbolic link pointing to your node_modules from within your public directory. The symlink will make it as if the files exist wherever the link is created.
授予对 node_modules 公共访问权限的最简单方法是从公共目录中创建一个指向 node_modules 的符号链接。符号链接将使它就像文件存在于创建链接的任何地方。
For example, if the node server has code for serving static files
例如,如果节点服务器有提供静态文件的代码
app.use(serveStatic(path.join(__dirname, 'dist')));
and __dirname refers to /path/to/app so that your static files are served from /path/to/app/dist
和 __dirname 指的是 /path/to/app 以便您的静态文件从 /path/to/app/dist 提供
and node_modules is at /path/to/app/node_modules, then create a symlink like this on mac/linux:
node_modules 位于 /path/to/app/node_modules,然后在 mac/linux 上创建这样的符号链接:
ln -s /path/to/app/node_modules /path/to/app/dist/node_modules
or like this on windows:
或者像这样在 Windows 上:
mklink /path/to/app/node_modules /path/to/app/dist/node_modules
Now a get request for:
现在获取请求:
node_modules/some/path
will receive a response with the file at
将在以下位置收到文件的响应
/path/to/app/dist/node_modules/some/path
which is really the file at
这是真正的文件
/path/to/app/node_modules/some/path
If your directory at /path/to/app/dist is not a safe location, perhaps because of interference from a build process with gulp or grunt, then you could add a separate directory for the link and add a new serveStatic call such as:
如果您在 /path/to/app/dist 的目录不是一个安全的位置,可能是因为 gulp 或 grunt 的构建过程的干扰,那么您可以为链接添加一个单独的目录并添加一个新的 serveStatic 调用,例如:
ln -s /path/to/app/node_modules /path/to/app/newDirectoryName/node_modules
and in node add:
并在节点中添加:
app.use(serveStatic(path.join(__dirname, 'newDirectoryName')));
回答by Timmmm
I didn't find any clean solutions (I don't want to expose the source of all my node_modules) so I just wrote a Powershell script to copy them:
我没有找到任何干净的解决方案(我不想公开所有 node_modules 的源代码),所以我只写了一个 Powershell 脚本来复制它们:
$deps = "leaflet", "leaflet-search", "material-components-web"
foreach ($dep in $deps) {
Copy-Item "node_modules/$dep/dist" "static/$dep" -Recurse
}
回答by Akash
This is what I have setup on my expressserver:
这是我在我的express服务器上设置的:
// app.js
const path = require('path');
const express = require('express');
const expressApp = express();
const nm_dependencies = ['bootstrap', 'jquery', 'popper.js']; // keep adding required node_modules to this array.
nm_dependencies.forEach(dep => {
expressApp.use(`/${dep}`, express.static(path.resolve(`node_modules/${dep}`)));
});
<!-- somewhere inside head tag -->
<link rel="stylesheet" href="bootstrap/dist/css/bootstrap.css" />
<!-- somewhere near ending body tag -->
<script src="jquery/dist/jquery.js" charset="utf-8"></script>
<script src="popper.js/dist/popper.js" charset="utf-8"></script>
<script src="bootstrap/dist/js/bootstrap.js" charset="utf-8"></script>
Good Luck...
祝你好运...
回答by SuperNova
I did the below changes to AUTO-INCLUDE the files in the index html. So that when you add a file in the folder it will automatically be picked up from the folder, without you having to include the file in index.html
我对索引 html 中的文件进行了以下更改。这样当您在文件夹中添加文件时,它会自动从文件夹中提取,而无需将文件包含在 index.html 中
//// THIS WORKS FOR ME
///// in app.js or server.js
var app = express();
app.use("/", express.static(__dirname));
var fs = require("fs"),
function getFiles (dir, files_){
files_ = files_ || [];
var files = fs.readdirSync(dir);
for (var i in files){
var name = dir + '/' + files[i];
if (fs.statSync(name).isDirectory()){
getFiles(name, files_);
} else {
files_.push(name);
}
}
return files_;
}
//// send the files in js folder as variable/array
ejs = require('ejs');
res.render('index', {
'something':'something'...........
jsfiles: jsfiles,
});
///--------------------------------------------------
///////// in views/index.ejs --- the below code will list the files in index.ejs
<% for(var i=0; i < jsfiles.length; i++) { %>
<script src="<%= jsfiles[i] %>"></script>
<% } %>

