NOde.js / Express App не может найти некоторые node_modules - PullRequest
0 голосов
/ 19 сентября 2018

Я использую несколько модулей Node / Express в своем приложении, и все работает отлично для каждого модуля, пока я const module = require('module');.Мне не нужно определять статический путь для этих модулей как app.use(express.static(path.join(__dirname, 'public')));.

Однако для модуля sweetalert , если я определю в своем layout.pug (базовый файл мопса) script(src="/node_modules/sweetalert/dist/sweetalert.min.js"), я получаю ошибку 404 (не найдена), если я не включу в app.js следующий статический путь: app.use("/node_modules", express.static(__dirname + "/node_modules"));.

Мой вопросЭто нормальное поведение или я что-то не так делаю?(Я немного запутался, почему мне нужно определить статический путь только для одного из нескольких модулей, которые я использую.

1 Ответ

0 голосов
/ 25 сентября 2018

Вот что происходит:

app.use(express.static(path.join(__dirname, 'public'))); объявляет, что публичный каталог доступен для браузера.Вы должны поместить все ваши внешние ресурсы в эту папку.Это поможет отделить то, к чему можно получить доступ с сервера, и то, что можно получить от клиента.

Когда вы ссылаетесь на script(src="/node_modules/sweetalert/dist/sweetalert.min.js"), браузер выдает 404, потому что этот файл не находится в общедоступном каталоге, поэтому он недоступен браузеру.

Добавление этой строки app.use("/node_modules", express.static(__dirname + "/node_modules")); "исправляет"ваша проблема, но теперь выставляет все ваши node_modules для браузера.Это, вероятно, не очень хорошая идея, и я уверен, что эксперт по безопасности может объяснить, почему этого не следует делать.

Как мне решить эту проблему: просмотрите код .pug и посмотрите все ресурсы, которые требуются вашему интерфейсу.Затем скопируйте их в общую папку и исправьте ссылки, чтобы использовать копию ресурса.

Вот пример сценария, который я использую для перемещения ресурсов из каталога node_module в каталог public / assets:

build.js:

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

const ASSETS = [
    'jquery/dist/jquery.min.js',
    'sweetalert/dist/sweetalert.min.js'
];

if (!fs.existsSync('./public/assets')){
    fs.mkdirSync('./public/assets');
}

ASSETS.map(asset => {
    let filename = asset.substring(asset.lastIndexOf("/") + 1);
    let from = path.resolve(__dirname, `./node_modules/${asset}`)
    let to = path.resolve(__dirname, `./public/assets/${filename}`)
    if (fs.existsSync(from)) {
        fs.createReadStream(from).pipe(fs.createWriteStream(to));
     } else {
        console.log(`${from} does not exist.\nUpdate the build.js script with the correct file paths.`)
        process.exit(1)
    }
});

, затем я обновляю свой package.json, чтобы включить его в сценарии:

package.json:

"scripts": {
    "build": "node ./build.js || true",
    "start": "node ./bin/www"
}

затем на любой из моих страниц просмотра я ссылаюсь на ресурс, используя новый путь

random.pug:

script(src="/assets/jquery.min.js")
script(src="/assets/sweetalert.min.js")

Наконец, перед развертыванием приложения вы должны выполнить следующую команду: npm run build затем npm start

Вам нужно будет запустить команду сборки только в том случае, если ваши внешние ресурсы изменятся.Поэтому, если вы когда-либо используете sweetalert.min.js, вам нужно будет запустить сборку только при первом запуске приложения.Если позже вы добавите еще один ресурс aNewResource.js, вам потребуется обновить файл build.js и снова запустить npm run build.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...