नोड_मॉडल फ़ोल्डर के अंदर स्थित लिपियों को कैसे शामिल किया जाए?


275

मेरे पास एक node_modulesHTML वेबसाइट में शामिल करने के लिए सबसे अच्छा अभ्यास से संबंधित प्रश्न है ।

कल्पना कीजिए कि मेरे node_modulesफ़ोल्डर में बूटस्ट्रैप है । अब वेबसाइट के उत्पादन संस्करण के लिए, मैं बूटस्ट्रैप स्क्रिप्ट और node_modulesफ़ोल्डर के अंदर स्थित CSS फाइलें कैसे शामिल करूंगा ? क्या यह उस फ़ोल्डर के अंदर बूटस्ट्रैप को छोड़ने और निम्नलिखित की तरह कुछ करने के लिए समझ में आता है?

<script src="./node_modules/bootstrap/dist/bootstrap.min.js"></script>

या क्या मुझे अपनी gulp फ़ाइल में नियम जोड़ने होंगे जो फिर उन फ़ाइलों को मेरे dist फोल्डर में कॉपी करें? या क्या यह बेहतर होगा कि किसी तरह अपने HTML फ़ाइल से स्थानीय बूटस्ट्रैप को पूरी तरह से हटा दें और इसे CDN संस्करण से बदल दें?


2
संबंधित विषय stackoverflow.com/questions/24397379/… । SO heres explino @Palak भंसाली को केवल एक की जरूरत है, क्या यह इस एकमात्र उद्देश्य के लिए बोवर को लागू करने का औचित्य साबित करता है उदाहरण के लिए एक gulp एक्सप्रेस ऐप सीधे npm से बूटस्ट्रैप कर रहा है, अब gulp में फ़ाइलों की पहुंच की आवश्यकता है, जो नोड_मॉड्यूल्स में हैं। क्या इस एकमात्र उद्देश्य के लिए अब बोवर की आवश्यकता के लिए एकल उपयोग के मामले को सही ठहराया जाता है? इस समस्या im में चल रहा है। मैं पहले से ही कंपोज़र, npm, gulp, grunt का उपयोग करता हूं, न ही व्यक्तिगत रूप से बोवर चाहते हैं, और न ही इस ऐप पर ग्रंट भी चाहते हैं।
१०

उत्कृष्ट सवाल जो एक सहज समाधान की आवश्यकता है!
सेडवेल

जवाबों:


297

आमतौर पर, आप अपने किसी भी आंतरिक पथ को उजागर नहीं करना चाहते हैं कि आपका सर्वर बाहरी दुनिया में कैसे संरचित है। आप /scriptsअपने सर्वर में एक स्टैटिक रूट बना सकते हैं जो अपनी फाइलों को जिस भी डायरेक्टरी में होता है वहां से रहता है "./node_modules/bootstrap/dist/"। फिर, आपके पृष्ठों का स्क्रिप्ट टैग इस तरह दिखता है:

<script src="/scripts/bootstrap.min.js"></script>

यदि आप नोड्ज के साथ एक्सप्रेस का उपयोग कर रहे थे, तो एक स्थैतिक मार्ग इस तरह सरल है:

app.use('/scripts', express.static(__dirname + '/node_modules/bootstrap/dist/'));

फिर, किसी भी ब्राउज़र अनुरोध /scripts/xxx.jsको स्वचालित रूप से आपकी distनिर्देशिका से प्राप्त किया जाएगा __dirname + /node_modules/bootstrap/dist/xxx.js

नोट: एनपीएम के नए संस्करणों ने शीर्ष स्तर पर अधिक चीजें डालीं, इसलिए इतना गहरा घोंसला नहीं बनाया है कि यदि आप एनपीएम के नए संस्करण का उपयोग कर रहे हैं, तो ओपी के प्रश्न और वर्तमान उत्तर में संकेत दिए गए पथ के नाम अलग होंगे। लेकिन, अवधारणा अभी भी वही है। आपको पता चलता है कि फ़ाइलें आपके सर्वर ड्राइव पर भौतिक रूप से स्थित हैं और आप उन फ़ाइलों के लिए एक छद्म मार्ग बनाने के लिए एक 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');
});

2
क्या मुझे उन लोगों को मैन्युअल रूप से कॉपी करने की आवश्यकता है या ऐसा करने का कोई ग्रंट तरीका है? मुझे लगता है कि किसी भी तरह से बूटस्ट्रैप फ़ोल्डर को पूरी तरह से कॉपी किया जाएगा /scriptsक्योंकि इस तरह से मॉड्यूल के अंदर किसी भी निर्भरता को बनाए रखा जाएगा।
क्रिस

@phpheini - शायद इससे मदद मिलेगी: stackoverflow.com/questions/18966485/… और यह npmjs.com/package/grunt-copy
jfriend00

1
@ रोबर्टोस्क्लर - नहीं, यह डुप्स के लिए जांच नहीं करता है। express.static()पहला मैच भेजता है। चूंकि प्रत्येक express.static()कथन केवल एक संभव मिलान पथ बनाता है, इसलिए एक express.static()कथन से डुप्लिकेट नहीं होना चाहिए । यदि आपके पास एक से अधिक express.static()कथन हैं, जिनमें से प्रत्येक का मिलान हो सकता है, तो आपके कोड में पहला वह है जिसका मैच उपयोग किया जाएगा। साथ ही, आपके पास वास्तव में एक ही नाम और संबंधित पथ के साथ एक से अधिक फाइलें नहीं होनी चाहिए express.static()। सबसे अच्छा अभ्यास यह है कि ऐसा न करें।
jfriend00

1
@ रोबर्टोस्क्लर - आपको बहुत, बहुत सावधान रहना होगा कि आप क्या करने के लिए अनियमित पहुँच प्रदान करते हैं। सामान्य तौर पर, आपको केवल express.static()एक निर्देशिका को इंगित करना चाहिए जिसमें केवल सार्वजनिक फाइलें शामिल हैं (उप-निर्देशिकाएं शामिल हैं)। इसलिए, मैं वास्तव में ऐसी परियोजना की कल्पना नहीं कर सकता जहाँ बहुत सारी distनिर्देशिकाएँ प्रकाशित की जा रही हों। यह मुझे बहुत ही असामान्य लगता है। शायद आप किसी विशिष्ट फ़ाइल या 2-3 फ़ाइलों के लिए एक विशिष्ट मार्ग बनाना चाहते हैं। उस स्थिति में, आप उन फ़ाइलों को अस्वीकार करने के लिए जिम्मेदार हैं। यह किसी भी तरह से चार script.jsफाइल करने के लिए आपको अच्छा करने के लिए नहीं जा रहा है ।
jfriend00

1
@RobertOschler - यदि आप मैच करने के लिए उनके सामने एक अनोखा रास्ता नहीं बनाते हैं, तो किसी भी कोड के लिए यह जानने का कोई तरीका नहीं /script.jsहै कि ब्राउज़र द्वारा अनुरोध किए जाने पर कौन सा सेवा करें । तो, सार उत्तर यह है कि आपको डुप्लिकेट फ़ाइलनामों की स्थिति को अस्तित्व में नहीं आने देना चाहिए क्योंकि यह एक हल करने योग्य समस्या नहीं है जब तक कि आपको प्रत्येक निर्देशिका फ़ाइलों के लिए एक अद्वितीय उपसर्ग की आवश्यकता न हो। फिर, डुप्लिकेट रूट नाम वैसे भी कोई समस्या नहीं हैं। एक विस्तृत सिफारिश के साथ अधिक विशिष्ट उत्तर के लिए, आपको सटीक विवरण के साथ अपना प्रश्न पोस्ट करना होगा।
jfriend00

18

मैं पथ npm मॉड्यूल का उपयोग करूँगा और फिर कुछ इस तरह से करूँगा:

var path = require('path');
app.use('/scripts', express.static(path.join(__dirname, 'node_modules/bootstrap/dist')));

महत्वपूर्ण: हम पथ का उपयोग करते हैं। सिस्टम एगोनास्टिक तरीके से जुड़ने वाले पथ बनाने के लिए, अर्थात विंडोज़ और यूनिक्स पर हमारे पास अलग-अलग पथ विभाजक (/) हैं।


ऊपर के रूप में डुप्लिकेट चिह्नित करें, path.join सिर्फ एक अतिरिक्त उपाय है, लेकिन फिर भी नोड_मॉड्यूलir में एक स्थिर पथ जोड़कर एक ही समाधान है।
१०

2
"path.join सिर्फ एक अतिरिक्त उपाय है, लेकिन फिर भी एक ही समाधान" एक ही समाधान नहीं है। कड़ाई से बोलते हुए यह सिस्टम विशिष्ट जॉइनिंग का उपयोग करता है (खिड़कियों और यूनिक्स में / / और विभाजकों को ध्यान में रखें)
अलेक्जेंडर इगोरोव

4
ठीक है, मैं आपकी बात देख रहा हूँ, हाँ इसके हमेशा सिस्टम अज्ञेय के लिए अच्छा है, मुझे पता नहीं था कि यह क्या था। यह बात बताने के लिए धन्यवाद। यह समझदारी होगी कि अपने उत्तर में वाक्य को जोड़ने के बजाय, कोड :-) प्रदान करने के बजाय, अपने कोड को समझाएं।
21

10

जैसा कि jfriend00 ने उल्लेख किया है कि आपको अपने सर्वर संरचना को उजागर नहीं करना चाहिए। आप अपनी प्रोजेक्ट निर्भरता फ़ाइलों को कुछ इस तरह कॉपी कर सकते हैं public/scripts। आप इसे इस तरह dep-linker के साथ बहुत आसानी से कर सकते हैं :

var DepLinker = require('dep-linker');
DepLinker.copyDependenciesTo('./public/scripts')
// Done

1
लिपियों srcएस तो कुछ इस तरह होगा /scripts/[package-name]/dist/file.min.js
जैकब फोर्ड

7

यदि आप एक त्वरित और आसान समाधान चाहते हैं (और आपके पास गुल स्थापित है)।

अपने में 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']);

इसका नकारात्मक पक्ष यह है कि यह स्वचालित नहीं है। हालाँकि, अगर आप की जरूरत है कुछ लिपियों और शैलियों की नकल की है (और एक सूची में रखा), यह काम करना चाहिए।


कोई इसे अपने पैकेज में जोड़ सकता है। लिपियों में 'scripts': {'install':'yarn gulp copy-modules'}, यार्न को पैकेज मैनेजर मानते हैं और पैकेज में गुलप स्थापित होता है।
टोड

6

निर्देशिका 'node_modules' वर्तमान निर्देशिका में नहीं हो सकती है, इसलिए आपको गतिशील रूप से पथ को हल करना चाहिए।

var bootstrap_dir = require.resolve('bootstrap')
                           .match(/.*\/node_modules\/[^/]+\//)[0];
app.use('/scripts', express.static(bootstrap_dir + 'dist/'));

+1, हालांकि मुझे नहीं लगता कि यह सभी मामलों में काम करेगा - egan npm लिंक्ड मॉड्यूल जो कि नोड_मॉड्यूल सबफ़ोल्डर में नहीं है
Alasdair McLeay

3

मैं इस प्रश्न को एक आसान समाधान के साथ अद्यतन करना चाहता हूं। नोड_मॉड्यूल के लिए एक प्रतीकात्मक लिंक बनाएं।

नोड_मॉड्यूल के लिए सार्वजनिक पहुंच प्रदान करने का सबसे आसान तरीका यह है कि आप अपने सार्वजनिक निर्देशिका के भीतर से अपने नोड_मॉड्यूल की ओर संकेत करते हुए एक प्रतीकात्मक लिंक बनाएं। सीलिंक इसे बना देगा जैसे लिंक मौजूद है, जहां भी फाइलें मौजूद हैं।

उदाहरण के लिए, यदि नोड सर्वर में स्थिर फ़ाइलों की सेवा के लिए कोड है

app.use(serveStatic(path.join(__dirname, 'dist')));

और __dirname / path / to / app को संदर्भित करता है ताकि आपकी स्थिर फ़ाइलों को / पथ / से / app / अधिक दूरी पर परोसा जाए

और node_modules / पथ / / to / app / node_modules पर है, तो मैक / लाइनक्स पर इस तरह एक सिम्कलिन बनाएं:

ln -s /path/to/app/node_modules /path/to/app/dist/node_modules

या खिड़कियों पर इस तरह:

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

यदि आपकी निर्देशिका / पथ / / से / एप्लिकेशन / डिस्टेंस कोई सुरक्षित स्थान नहीं है, तो शायद एक निर्माण प्रक्रिया से जुड pathे या ग्रंट के साथ हस्तक्षेप के कारण, तो आप लिंक के लिए एक अलग निर्देशिका जोड़ सकते हैं और एक नया सर्विसस्टेटिक कॉल जोड़ सकते हैं जैसे:

ln -s /path/to/app/node_modules /path/to/app/newDirectoryName/node_modules

और नोड में जोड़ें:

app.use(serveStatic(path.join(__dirname, 'newDirectoryName')));

1
लेकिन तब आपने अपने ऐप को एक अलग पथ पर ले जाया है और सिमलिंक अमान्य है। या आप अपने ऐप को एक अलग मशीन (परीक्षण / प्रोडक्ट) पर चलाना चाहते हैं, आपको इसे फिर से बनाना होगा। आपके ऐप में किसी भी योगदानकर्ता को ऐसा ही करना होगा। यह उपरोक्त समाधानों में कुछ मुख्य बिंदुओं को जोड़ता है।
mati.o

@ mati.o रिश्तेदार प्रतीकात्मक लिंक के बारे में क्या? मुझे यह समाधान पसंद है, लेकिन केवल रिश्तेदार सहानुभूति के साथ।
लुकास बेदनाřक

3

मुझे कोई साफ़ समाधान नहीं मिला (मैं अपने सभी नोड_मॉड्यूल्स के स्रोत को उजागर नहीं करना चाहता) इसलिए मैंने उन्हें कॉपी करने के लिए एक पॉवर्सशेल स्क्रिप्ट लिखी:

$deps = "leaflet", "leaflet-search", "material-components-web"

foreach ($dep in $deps) {
    Copy-Item "node_modules/$dep/dist" "static/$dep" -Recurse
}

1

मैंने इंडेक्स html में फाइलों को AUTO-INCLUDE करने के लिए नीचे किए गए बदलाव किए। ताकि जब आप फ़ोल्डर में कोई फ़ाइल जोड़ते हैं, तो यह स्वचालित रूप से फ़ोल्डर से उठाया जाएगा, इसके बिना आपको फ़ाइल को 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>
<% } %>

1

यह वही है जो मैंने अपने 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>

शुभ लाभ...

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.