У меня есть вопрос относительно лучшей практики включения node_modules
в HTML-сайт.
Представьте, что у меня есть Bootstrap в папке node_modules
. Теперь для производственной версии сайта, как мне включить скрипт Bootstrap и CSS файлы, расположенные в папке node_modules
? Имеет ли смысл оставить Bootstrap в этой папке и сделать что-то вроде следующего?
<script src="./node_modules/bootstrap/dist/bootstrap.min.js"></script>
Или мне придется добавить правила в файл gulp, которые затем скопируют эти файлы в папку dist? Или лучше позволить gulp каким-то образом полностью удалить локальный bootstrap из моего HTML-файла и заменить его версией из CDN?
Обычно вы не хотите открывать внешнему миру внутренние пути к структуре вашего сервера. Вы можете сделать статический маршрут /scripts' на вашем сервере, который будет получать свои файлы из любой директории, в которой они находятся. Так, если ваши файлы находятся в каталоге
"./node_modules/bootstrap/dist/"`. Тогда тег script на ваших страницах выглядит следующим образом:
<script src="/scripts/bootstrap.min.js"></script>
Если вы использовали express с nodejs, статический маршрут выглядит следующим образом:
app.use('/scripts', express.static(__dirname + '/node_modules/bootstrap/dist/'));
Тогда все запросы браузера к /scripts/xxx.js
будут автоматически извлекаться из вашего каталога dist
по адресу __dirname + /node_modules/bootstrap/dist/xxx.js
.
Примечание: Новые версии NPM размещают больше вещей на верхнем уровне, не вложенных так глубоко, поэтому если вы используете новую версию NPM, то имена путей будут отличаться от указанных в вопросе OP'и в текущем ответе. Но концепция остается той же. Вы выясняете, где физически расположены файлы на диске вашего сервера, и делаете app.use()
с express.static()
для создания псевдо-пути к этим файлам, чтобы не раскрывать клиенту реальную организацию файловой системы сервера.
Если вы не хотите создавать такой статический маршрут, то вам, вероятно, лучше просто скопировать публичные скрипты в путь, который ваш веб-сервер воспринимает как /scripts
или любое другое обозначение верхнего уровня, которое вы хотите использовать. Обычно такое копирование можно сделать частью процесса сборки/развертывания.
Если вы хотите сделать публичным только один конкретный файл в каталоге, а не все, что находится в этом каталоге, то вы можете вручную создать отдельные маршруты для каждого файла, а не использовать express.static()
, например:
<script src="/bootstrap.min.js"></script>
И код для создания маршрута для этого
app.get('/bootstrap.min.js', function(req, res) {
res.sendFile(__dirname + '/node_modules/bootstrap/dist/bootstrap.min.js');
});
Или, если вы хотите по-прежнему разграничивать маршруты для скриптов с помощью /scripts
, вы можете сделать следующее:
<script src="/scripts/bootstrap.min.js"></script>
И код для создания маршрута для этого
app.get('/scripts/bootstrap.min.js', function(req, res) {
res.sendFile(__dirname + '/node_modules/bootstrap/dist/bootstrap.min.js');
});
Я бы использовал модуль path npm, а затем сделал бы что-то вроде этого:
var path = require('path');
app.use('/scripts', express.static(path.join(__dirname, 'node_modules/bootstrap/dist')));
Как отметил jfriend00 вы не должны подвергать вашу структуру сервера. Вы можете скопировать ваши файлы зависимостей проекта что-то вроде общественных/скрипты
. Вы можете сделать это очень легко с ДЭП-линкер, например:
var DepLinker = require('dep-linker');
DepLinker.copyDependenciesTo('./public/scripts')
// Done
Директория 'node_modules' может не находиться в текущей директории, поэтому путь следует определять динамически.
var bootstrap_dir = require.resolve('bootstrap')
.match(/.*\/node_modules\/[^/]+\//)[0];
app.use('/scripts', express.static(bootstrap_dir + 'dist/'));
Если вы хотите быстрое и простое решение (и вы установили залпом).
В моем gulpfile.jsя бегу простого копирования вставки, что добавляет каких-либо файлов мне может понадобиться в
./каталог общественных/модули/`.
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']);
Недостатком этого является то, что это'т автоматизированы. Однако, если все, что вам нужно, это несколько скриптов и стилей, скопированных (и сохранил в списке), это должно сделать работу.
Я хочу, чтобы обновить этот вопрос с простым решением. Создать символьную ссылку для папки node_modules.
Самый простой способ предоставить общий доступ к папки node_modules-создать символическую ссылку, указывающую на ваш папки node_modules из публичных каталогов. Символическая ссылка будет сделать это, как если файлы существуют, где создается ссылка.
Например, если узел сервера код для обслуживания статических файлов
app.use(serveStatic(path.join(__dirname, 'dist')));
и __каталог ссылается на /путь/к/приложению, так что ваши статические файлы отдаются с /путь/к/приложению/дист
и папки node_modules в /путь/к/приложению/папки node_modules, а затем создать символическую ссылку, как это на Mac/Линукс:
ln -s /path/to/app/node_modules /path/to/app/dist/node_modules
или как это на Windows:
mklink /path/to/app/node_modules /path/to/app/dist/node_modules
Теперь вам запрос:
node_modules/some/path
получите ответ с файлом в
/path/to/app/dist/node_modules/some/path
которая на самом деле файл в
/path/to/app/node_modules/some/path
Если ваш каталог /путь/к/приложению/р-не безопасное место, возможно, из-за помех от процесса сборки Gulp или Grunt, то тогда можно добавить отдельный каталог по ссылке и добавить новый serveStatic назвать такие как:
ln -s /path/to/app/node_modules /path/to/app/newDirectoryName/node_modules
и в узел добавить:
app.use(serveStatic(path.join(__dirname, 'newDirectoryName')));
Я не'т найти любые чистые решения (я не'т хотим, чтобы разоблачить источник всех моих папки node_modules) поэтому я просто написал скрипт PowerShell, чтобы скопировать их:
$deps = "leaflet", "leaflet-search", "material-components-web"
foreach ($dep in $deps) {
Copy-Item "node_modules/$dep/dist" "static/$dep" -Recurse
}
Я сделал ниже изменения автоматически включать файлы в индекс 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>
<% } %>
Это то, что я на "экспресс" сервера:
// 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>
Удачи...