2014-10-28 5 views
16

मेरे बालों को खींचकर सरल कोड को साझा करने के लिए समाधान, एनपीएम के माध्यम से, कई ब्राउज़र या वेबपैक बंडलों में आवश्यक है। सोच रहा है, क्या फाइल "ब्रिज" जैसी चीज है?एकाधिक ब्राउज़र या वेबपैक बंडलों में एनपीएम के माध्यम से लोड मॉड्यूल साझा करने के लिए सरल समाधान

यह संकलन समय (मुझे देखने के बारे में पता है) के कारण नहीं है बल्कि मेरे सभी विक्रेता विशिष्ट libs को vendor.js में निकालने की इच्छा है ताकि मेरा app.js फाइलसाइज डाउन हो और ब्राउज़र को बड़े पैमाने पर क्रैश न किया जा सके sourcemaps। इसके अलावा, मुझे लगता है कि संकलित जेएस उत्पन्न करने की आवश्यकता को क्लीनर चाहिए। और हां:

// vendor.js 

require('react'); 
require('lodash'); 
require('other-npm-module'); 
require('another-npm-module'); 

इसकी बहुत महत्वपूर्ण है कि कोड NPM से के रूप में करने का विरोध किया बोवर, या क्रम में कुछ 'विक्रेता' निर्देशिका में बचाया एक रिश्तेदार पथ के माध्यम से आयात किया है और पहचान होने की एक परत के माध्यम से लोड किया जा। मैं अपने वास्तविक अनुप्रयोग स्रोत को छोड़कर एनपीएम के माध्यम से हर लाइब्रेरी संदर्भ खींचना चाहता हूं।

app.js में मैं अपने sourcecode के सभी रखने के लिए, और externals सरणी के माध्यम से, बाहर संकलन से ऊपर सूचीबद्ध विक्रेता पुस्तकालयों:

// app.js 

var React = require('react'); 
var _  = require('lodash'); 

var Component = React.createClass() 

// ... 

और फिर index.html में, मैं की आवश्यकता होती है दोनों फ़ाइलों

// index.html 
<script src='vendor.js'></script> 
<script src='app.js'></script> 

ब्राउज़र या वेबपैक का उपयोग करके, मैं इसे कैसे बना सकता हूं ताकि app.js एनपीएम के माध्यम से लोड किए गए मॉड्यूल में "देख" सकें? मुझे बाहरी के साथ एक बंडल बनाने और फिर एक उपनाम के माध्यम से सीधे फ़ाइल (संदर्भ में, node_modules) का संदर्भ देने के बारे में पता है, लेकिन मैं एक ऐसे समाधान को ढूंढने की उम्मीद कर रहा हूं जो अधिक स्वचालित और कम "Requ.js" जैसा है।

असल में, मुझे आश्चर्य है कि दोनों को पुल करना संभव है ताकि app.js निर्भरता को हल करने के लिए vendor.js के अंदर देख सकें। यह एक सरल, सीधा ऑपरेशन जैसा प्रतीत होता है लेकिन मुझे इस चौड़े, व्यापक वेब पर कहीं भी जवाब नहीं मिल रहा है।

धन्यवाद!

उत्तर

11

वेबपैक के साथ आप एकाधिक प्रविष्टि बिंदुओं और CommonChunkPlugin का उपयोग करेंगे।

webpack docs से लिया:


2 फ़ाइलों में अपने एप्लिकेशन को विभाजित करने के लिए, कहते हैं कि app.js और vendor.js, आप vendor.js में विक्रेता फ़ाइलों की आवश्यकता कर सकते हैं। फिर नीचे दिखाए गए अनुसार इस नाम को CommonChunkPlugin पर पास करें।

module.exports = { 
    entry: { 
    app: "./app.js", 
    vendor: ["jquery", "underscore", ...], 
    }, 
    output: { 
    filename: "bundle.js" 
    }, 
    plugins: [ 
    new webpack.optimize.CommonsChunkPlugin(
     /* chunkName= */"vendor", 
     /* filename= */"vendor.bundle.js" 
    ) 
    ] 
}; 

यह ऐप खंड से विक्रेता खंड में सभी मॉड्यूल को हटा देगा। bundle.js में अब आपकी ऐप कोड शामिल होगी, इसकी किसी भी निर्भरता के बिना। ये vendor.bundle.js में हैं।

अपने HTML पृष्ठ लोड vendor.bundle.jsbundle.js से पहले लोड करें।

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

+0

मैं प्रतिक्रिया यह मानें कि विक्रेता सरणी में भी चला जाता है? – Leahcim

+0

क्या आप उस सरणी में विक्रेता फ़ाइल का नाम शामिल कर रहे हैं, या इसे इसके लिए पथ होना चाहिए? – Leahcim

+0

मैं प्रोजेक्ट्स के बीच साझा करने वाले घटकों की अपनी अलग लाइब्रेरी के लिए एक अलग बंडल या हिस्सा नहीं बनाना चाहता हूं, मैं सिर्फ स्रोत फ़ाइलों की आवश्यकता नहीं चाहता हूं। क्या आपको ऐसा करने का कोई तरीका पता है? (पूर्ण प्रश्न: http://stackoverflow.com/questions/31820641/how-to-set-up-a-private-shared-library-of-react-components-with-webpack) – Andy

26

लिस्टिंग सभी विक्रेता फ़ाइलें/मॉड्यूल और का उपयोग कर CommonChunkPlugin वास्तव में सुझाया गया तरीका है। हालांकि यह बहुत कठिन हो जाता है, और त्रुटि प्रवण।

इन एनपीएम मॉड्यूल पर विचार करें: fastclick और mprogress। चूंकि वे CommonJS मॉड्यूल प्रारूप को नहीं अपनाया है, तो आप, webpack सहारा देने के लिए की जरूरत है इस तरह:

require('imports?define=>false!fastclick')(document.body); 
require('mprogress/mprogress.min.css'); 
var Mprogress = require('mprogress/mprogress.min.js'), 

अब यह सोचते हैं कि आप दोनों fastclick और अपने विक्रेता हिस्सा में mprogress चाहेगा, तो आप शायद इस कोशिश करेंगे:

module.exports = { 
    entry: { 
    app: "./app.js", 
    vendor: ["fastclick", "mprogress", ...] 

हां, यह काम नहीं करता है।

module.exports = { 
    entry: { 
    app: "./app.js", 
    vendor: [ 
     "imports?define=>false!fastclick", 
     "mprogress/mprogress.min.css", 
     "mprogress/mprogress.min.js", 
     ...] 

यह पुराने हो जाता है, यहां तक ​​कि कुछ resolve.alias प्रवंचना के साथ: आप require() के लिए कॉल मैच के लिए की जरूरत है। मेरा कामकाज यहाँ है। CommonChunkPlugin आपको कॉलबैक निर्दिष्ट करने देता है जो विक्रेता खंड में मॉड्यूल को शामिल करना चाहे या नहीं, वापस लौटाएगा। अपने स्वयं के स्रोत कोड एक विशिष्ट src निर्देशिका में है, और बाकी node_modules निर्देशिका में है, तो सिर्फ अपने रास्ते पर आधारित मॉड्यूल अस्वीकार:

var node_modules_dir = path.join(__dirname, 'node_modules'), 
    app_dir   = path.join(__dirname, 'src'); 

module.exports = { 
    entry: { 
    app: "./app.js", 
    }, 
    output: { 
    filename: "bundle.js" 
    }, 
    plugins: [ 
    new webpack.optimize.CommonsChunkPlugin(
     /* chunkName= */"vendor", 
     /* filename= */"vendor.bundle.js" 
     function (module, count) { 
     return module.resource && module.resource.indexOf(app_dir) === -1; 
     } 
    ) 
    ] 
}; 

कहाँ module.resource मॉड्यूल के लिए पथ है विचार किया जा रहा। तुम भी विपरीत कर सकता है, और केवल मॉड्यूल में शामिल हैं, तो इसके अंदर node_modules_dir है, अर्थात्:

 return module.resource && module.resource.indexOf(node_modules_dir) === 0; 

लेकिन मेरी स्थिति में, मैं नहीं बल्कि कहेंगे: "सब कुछ है कि मेरे स्रोत स्रोत पेड़ में नहीं है डाल एक विक्रेता खंड में "।

उम्मीद है कि मदद करता है।

+0

'src' निर्देशिका में '।/App.js' फ़ाइल है? – Leahcim

+0

भी, यह कैसे काम करता है जहां आपके पास एनपीएम मॉड्यूल हैं जिनका उपयोग आप विकास के लिए करते हैं लेकिन उत्पादन विक्रेता फ़ाइल में नहीं चाहते हैं? उदाहरण के लिए, कहें कि आपके पास 'Backbone.js' और' underscore.js' 'node_module' है, जिसे आपको विक्रेता फ़ाइल में चाहिए, लेकिन अन्य 'node_modules' भी हैं जिन्हें केवल dev उद्देश्यों के लिए शामिल किया गया था और आप नहीं करते हैं एक vendor.bundle.js' में बंडल करना चाहते हैं – Leahcim

+0

@Leahcim ऐसा लगता है कि जब आप "dev only" मॉड्यूल लोड करते हैं, तो आपको वेबपैक.कॉन्फिग फ़ाइल में नहीं लोड करने की आवश्यकता होती है। आप 'IS_DEV' को परिभाषित करने के लिए 'DefinePlugin' जैसे कुछ का उपयोग कर सकते हैं और सशर्त रूप से आपके dev node_modules की आवश्यकता होती है .. फिर यदि आप' IS_DEV' गलत हैं, तो संकलित करते हैं, तो यह पहले स्थान पर लोड नहीं होगा –

संबंधित मुद्दे