Webpack के साथ डायरेक्टरी बनाने के लिए स्टैटिक फाइल्स को कॉपी कैसे करें?


330

मैं से स्थानांतरित करने के लिए कोशिश कर रहा हूँ Gulpकरने के लिए Webpack। में Gulpमैं काम जो प्रतियां से सभी फ़ाइलों और फ़ोल्डरों है / स्थिर / फ़ोल्डर में / निर्माण / फ़ोल्डर। उसी के साथ कैसे करें Webpack? क्या मुझे कुछ प्लगइन की आवश्यकता है?


2
गुलाब समझने के लिए बहुत अच्छा है। बस gulpfile.js से webpack फोन अगर आप चाहते हैं
बेरिऑन ली

यदि आप लारवेल मिक्स का उपयोग कर रहे हैं, तो laravel.com/docs/5.8/mix#copying-files-and-directories उपलब्ध है।
रियान

जवाबों:


179

आपको चीजों को कॉपी करने की जरूरत नहीं है, वेबपैक gulp से अलग काम करता है। वेबपैक एक मॉड्यूल बंडल है और आपकी फ़ाइलों में आपके द्वारा संदर्भित सभी चीजें शामिल की जाएंगी। आपको बस उसके लिए एक लोडर निर्दिष्ट करने की आवश्यकता है।

इसलिए यदि आप लिखते हैं:

var myImage = require("./static/myImage.jpg");

वेबपैक पहले संदर्भित फ़ाइल को जावास्क्रिप्ट के रूप में पार्स करने का प्रयास करेगा (क्योंकि यह डिफ़ॉल्ट है)। बेशक, वह विफल हो जाएगा। इसलिए आपको उस फ़ाइल प्रकार के लिए एक लोडर निर्दिष्ट करने की आवश्यकता है। फ़ाइल - या यूआरएल-लोडर उदाहरण के लिए संदर्भित फ़ाइल ले, यह webpack के आउटपुट फ़ोल्डर में डाल दिया (जो होना चाहिए buildआपके मामले में) और उस फ़ाइल के लिए हैश किया गया URL वापस जाएँ।

var myImage = require("./static/myImage.jpg");
console.log(myImage); // '/build/12as7f9asfasgasg.jpg'

आमतौर पर लोडर वेबपैक कॉन्फिगर के माध्यम से लागू होते हैं:

// webpack.config.js

module.exports = {
    ...
    module: {
        loaders: [
            { test: /\.(jpe?g|gif|png|svg|woff|ttf|wav|mp3)$/, loader: "file" }
        ]
    }
};

बेशक आपको यह काम करने के लिए पहले फ़ाइल-लोडर को स्थापित करना होगा।


42
" बेशक आपको यह काम करने के लिए पहले फ़ाइल-लोडर को स्थापित करने की आवश्यकता है । " यहां "फ़ाइल-लोडर" के लिए उपरोक्त लिंक करें । और यहां बताया गया है कि इसे कैसे इंस्टॉल करें और इसका उपयोग करें।
नैट

21
आपके पास अभी भी HTML फ़ाइलों की समस्या है और उनमें सभी संदर्भ लोड नहीं किए जा रहे हैं।
किलियनक डेसी

125
हाँ, यदि आप वेबपेक प्लगइन्स के नरक में जाना चाहते हैं, तो आप फ़ाइल-लोडर, सीएसएस-लोडर, स्टाइल-लोडर, यूआरएल-लोडर ... का उपयोग कर सकते हैं ... और फिर आपके पास इसकी आवश्यकता होने पर इसे कॉन्फ़िगर करने का एक शानदार समय हो सकता है। और गुगली करना और नींद न
आना

11
@ KamilTomšík तो आपकी सिफारिश है कि हमें वेबपैक प्लगइन्स से बचने के लिए वेबपैक प्लगइन का उपयोग करना चाहिए? (बस मजाक कर रहा हूं। मुझे आपकी बात मिल गई।)
कोनराड विल्टरनस्ट

12
ठीक है, सभी छवियों का अधिकांश हिस्सा css और html में है। तो क्या मुझे आवश्यकता ('img.png') का उपयोग करके अपने जेएस फाइलों में इन सभी छवियों की आवश्यकता होनी चाहिए; उस फ़ाइल-लोडर के साथ काम करने के लिए यह काफी पागल बात है।
रांटिवे

579

फ़ाइल-लोडर मॉड्यूल का उपयोग कर संपत्ति की आवश्यकता है जिस तरह से वेबपैक का उपयोग करने का इरादा है ( स्रोत )। हालाँकि, यदि आपको अधिक लचीलेपन की आवश्यकता है या आप क्लीनर इंटरफ़ेस चाहते हैं, तो आप सीधे मेरे copy-webpack-plugin( npm , Github ) का उपयोग करके स्थिर फ़ाइलों को भी कॉपी कर सकते हैं । अपने लिए staticकरने के लिए buildउदाहरण:

const CopyWebpackPlugin = require('copy-webpack-plugin');

module.exports = {
    context: path.join(__dirname, 'your-app'),
    plugins: [
        new CopyWebpackPlugin([
            { from: 'static' }
        ])
    ]
};

11
यह बहुत सरल है जब आप एक पूरी निर्देशिका (यानी स्थिर HTML, और अन्य बॉयलरप्लेट छवियों) की प्रतिलिपि बनाना चाहते हैं!
अर्जुन मेहता

6
क्या चाल है, धन्यवाद :) फ़ाइल लोडर पर छोड़ दिया कई असफल प्रयासों के बाद इसे एक बहुत ही सरल कमांड करने के लिए। आपके प्लगइन ने पहली बार काम किया।
आर्केलडॉन

3
@ वे प्लग-इन फ़ाइलों को फिर से कॉपी करते हैं यदि वे बदलते हैं (देव-सर्वर या वेबपैक - वॉच)। यदि यह आपके लिए कॉपी नहीं है, तो कृपया एक समस्या दर्ज करें।
जुलाव

2
मैं वेबपैक के लिए नया हूं, लेकिन मुझे यह समझने में कठिन समय हो रहा है कि हमें फाइल-लोडर / url-loader / img-loader का उपयोग करने की आवश्यकता क्यों है ... बजाय उन्हें कॉपी करने के? फ़ाइल-लोडर के साथ ऐसा करने से हमें क्या लाभ होता है?
BreakDS

2
चूंकि आप प्लगइन लेखक हैं। इस प्रश्न को पूछने की कोई बेहतर गति नहीं है। "कॉपी-वेबपैक-प्लगइन" प्लगइन का उपयोग करके ... क्या मैं स्रोत निर्देशिका से फ़ाइलों को फ़िल्टर कर सकता हूं, ताकि यह केवल कुछ फ़ाइल एक्सक्लूसिव एक्स के साथ फाइल को कॉपी करे। केवल ".html" कॉपी करें? सादर
DevWL

56

यदि आप अपनी स्टैटिक फ़ाइलों की प्रतिलिपि बनाना चाहते हैं, तो आप फ़ाइल-लोडर का इस तरह से उपयोग कर सकते हैं:

HTML फ़ाइलों के लिए:

webpack.config.js में:

module.exports = {
    ...
    module: {
        loaders: [
            { test: /\.(html)$/,
              loader: "file?name=[path][name].[ext]&context=./app/static"
            }
        ]
    }
};

आपकी js फ़ाइल में:

  require.context("./static/", true, /^\.\/.*\.html/);

./static/ आपकी js फ़ाइल कहाँ है के सापेक्ष है।

आप छवियों के साथ या जो भी कर सकते हैं। संदर्भ का पता लगाने के लिए एक शक्तिशाली तरीका है !!


3
मैं इस विधि को कॉपी-वेबपैक-प्लगइन मॉड्यूल पर पसंद करता हूं। इसके अतिरिक्त, मैं अपने वेबपैक विन्यास में "& संदर्भ =। / App / static" का उपयोग किए बिना इसे प्राप्त करने में सक्षम था। मुझे केवल आवश्यकता थी। संदर्भ लाइन।
डेव लैंड्री

2
मैं यह कोशिश कर रहा हूँ, यह बहुत अच्छा लग रहा है लेकिन एक छोटी सी समस्या के लिए जो मुझे मिल रहा है, वह यह है कि यह index.htmlएक उपनिर्देशिका में डाल रहा है जिसे यह कहा _जा रहा है (अंडरस्कोर), क्या चल रहा है?
क्रिश २

2
जब आप "अपने जेएस फ़ाइल में" कहते हैं तो आपका क्या मतलब है? अगर मेरे पास जेएस फाइल नहीं है तो क्या होगा?
एवोल्यूशनबॉक्स

पूर्ण रूप से। प्रविष्टि स्क्रिप्ट में यह एक पंक्ति, फ़ोल्डर के main.jsभीतर सब कुछ आयात कर रही है static:require.context("./static/", true, /^.*/);
मारियो

2
यह एक साफ-सुथरी हैक है लेकिन अगर आप बहुत सारी फाइलों को कॉपी कर रहे हैं तो आप मेमोरी से बाहर चले जाएंगे।
टॉम

18

एक फायदा जो उपरोक्त कॉपी-वेबपैक-प्लगइन लाता है, जो पहले नहीं बताया गया है, वह यह है कि यहां बताए गए अन्य सभी तरीके अभी भी आपकी बंडल फ़ाइलों में संसाधनों को बंडल करते हैं (और आपको उन्हें कहीं "आवश्यकता" या "आयात" करने की आवश्यकता होती है)। अगर मैं बस कुछ छवियों को चारों ओर या कुछ टेम्पलेट धारावाहिकों में स्थानांतरित करना चाहता हूं, तो मैं अपनी जावास्क्रिप्ट बंडल फ़ाइल को बेकार संदर्भों के साथ बंद नहीं करना चाहता, मैं सिर्फ सही जगह पर फ़ाइलों को उत्सर्जित करना चाहता हूं। मुझे वेबपैक में ऐसा करने का कोई अन्य तरीका नहीं मिला है। निश्चित रूप से यह नहीं है कि मूल रूप से किस वेबपैक के लिए डिज़ाइन किया गया था, लेकिन यह निश्चित रूप से वर्तमान उपयोग का मामला है। (@BreakDS मुझे उम्मीद है कि यह आपके सवाल का जवाब देता है - यह केवल एक लाभ है अगर आप इसे चाहते हैं)


7

उपरोक्त सुझाव अच्छे हैं। लेकिन सीधे अपने प्रश्न का उत्तर देने का प्रयास करने के लिए मैं आपके द्वारा cpy-cliपरिभाषित स्क्रिप्ट का उपयोग करने का सुझाव दूंगा package.json

यह उदाहरण nodeआपके रास्ते पर कहीं न कहीं उम्मीद करता है। cpy-cliविकास निर्भरता के रूप में स्थापित करें :

npm install --save-dev cpy-cli

फिर कुछ नोड्स फ़ाइलें बनाएँ। एक कॉपी करने के लिए और दूसरा एक चेकमार्क और संदेश प्रदर्शित करने के लिए।

copy.js

#!/usr/bin/env node

var shelljs = require('shelljs');
var addCheckMark = require('./helpers/checkmark');
var path = require('path');

var cpy = path.join(__dirname, '../node_modules/cpy-cli/cli.js');

shelljs.exec(cpy + ' /static/* /build/', addCheckMark.bind(null, callback));

function callback() {
  process.stdout.write(' Copied /static/* to the /build/ directory\n\n');
}

checkmark.js

var chalk = require('chalk');

/**
 * Adds mark check symbol
 */
function addCheckMark(callback) {
  process.stdout.write(chalk.green(' ✓'));
  callback();
}

module.exports = addCheckMark;

में स्क्रिप्ट जोड़ें package.json। मान लीजिए स्क्रिप्ट में हैं<project-root>/scripts/

...
"scripts": {
  "copy": "node scripts/copy.js",
...

सरपट चलाने के लिए:

npm run copy


3
ओपी npm लिपियों का उपयोग न करते हुए वेबपैक के अंदर जाने वाली फ़ाइल को पूरा करना चाहता था?
विलियम एस।

जब ओपी वेबपैक के अंदर इसे हल करना चाहता था, तब भी यह संभव है कि वह npm के माध्यम से वेबपैक चला रहा है, इसलिए वह इसे अपनी बिल्ड स्क्रिप्ट में जोड़ सकता है जहां वेबपैक चलाया जाता है
पीरो का कहना है कि मोनिका

5

सबसे अधिक संभावना है कि आपको CopyWebpackPlugin का उपयोग करना चाहिए जिसका उल्लेख kevlened उत्तर में किया गया था। वैकल्पिक रूप से कुछ तरह की फाइलों जैसे .html या .json के लिए आप रॉ-लोडर या json-loader का भी उपयोग कर सकते हैं। इसके माध्यम से इंस्टॉल करें npm install -D raw-loaderऔर फिर आपको केवल हमारी webpack.config.jsफ़ाइल में एक और लोडर जोड़ने की आवश्यकता है ।

पसंद:

{
    test: /\.html/,
    loader: 'raw'
}

नोट: किसी भी परिवर्तन को प्रभावी करने के लिए वेबपैक-देव-सर्वर को पुनः आरंभ करें।

और अब आपको रिश्तेदार पथों का उपयोग करके HTML फ़ाइलों की आवश्यकता हो सकती है, इससे फ़ोल्डर्स को इधर-उधर ले जाना आसान हो जाता है।

template: require('./nav.html')  

5

जिस तरह से मैं स्थिर लोड करता हूं imagesऔर fonts:

module: {
    rules: [
      ....

      {
        test: /\.(jpe?g|png|gif|svg)$/i,
        /* Exclude fonts while working with images, e.g. .svg can be both image or font. */
        exclude: path.resolve(__dirname, '../src/assets/fonts'),
        use: [{
          loader: 'file-loader',
          options: {
            name: '[name].[ext]',
            outputPath: 'images/'
          }
        }]
      },
      {
        test: /\.(woff(2)?|ttf|eot|svg|otf)(\?v=\d+\.\d+\.\d+)?$/,
        /* Exclude images while working with fonts, e.g. .svg can be both image or font. */
        exclude: path.resolve(__dirname, '../src/assets/images'),
        use: [{
          loader: 'file-loader',
          options: {
            name: '[name].[ext]',
            outputPath: 'fonts/'
          },
        }
    ]
}

file-loaderउस काम करने के लिए स्थापित करने के लिए मत भूलना ।


आप डुप्लिकेट फ़ाइल नाम कैसे संभालते हैं? या बेहतर अभी तक, आप नए आउटपुट निर्देशिका में मूल पथ को संरक्षित करने के किसी भी तरीके के बारे में जानते हैं?
छावनी

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

1
यदि आप घटक आधारित विकास को लागू कर रहे हैं (जिनमें से एक मुख्य सिद्धांत इनकैप्सुलेशन है और विशेष रूप से इस मामले में जानकारी छिपाना ) , तो आपने जो भी उल्लेख किया है, वह कोई भी नहीं है। जब कोई व्यक्ति प्रोग्राम में एक नया घटक जोड़ता है, तो उन्हें यह जांचने की आवश्यकता नहीं होती है कि क्या कोई अन्य नाम की छवि है logo.pngऔर न ही उन्हें वैश्विक टकराव से बचने के लिए एक obtuse और "उम्मीद" अद्वितीय फ़ाइल नाम बनाना होगा। उसी कारण से हम CSS मॉड्यूल का उपयोग करते हैं ।
19

1
जैसा कि मैं मूल पथ और फ़ाइल नाम को बनाए रखने के लिए छवियां क्यों चाहता हूं; डिबगिंग ज्यादातर, एक ही कारण आप sourcemaps का उपयोग करेंगे, लेकिन यह भी एसईओ । बावजूद, मेरे प्रश्न का उत्तर वास्तव में बहुत सरल था ... [path][name].[ext]और विशिष्ट वातावरण या उपयोग के मामले में इसे संशोधित करने के लिए बहुत लचीलापन प्रदान किया गया है ... फ़ाइल-लोडर
cantuket

1
कहा जा रहा है कि हमने आपके उदाहरण की भिन्नता को लागू किया है इसलिए आपको प्रदान करने के लिए धन्यवाद!
कैंटुकेट

3

आप अपने पैकेज में बैश लिख सकते हैं। json:

# package.json
{
  "name": ...,
  "version": ...,
  "scripts": {
    "build": "NODE_ENV=production npm run webpack && cp -v <this> <that> && echo ok",
    ...
  }
}

1
विंडोज में, cp के बजाय बस xcopy का उपयोग करें:"build": "webpack && xcopy images dist\\images\\ /S /Y && xcopy css dist\\css\\ /S /Y"
23

7
ठीक है, इसलिए आपका समाधान प्रत्येक ओएस के लिए एक अलग स्क्रिप्ट है?
मैकीज डरबन

हां, मेरे लिए प्रत्येक OS के लिए एक स्क्रिप्ट स्वीकार्य है (यह वास्तव में यूनिक्स / गैर-यूनिक्स है, क्योंकि लिनक्स पर एक स्क्रिप्ट डार्विन या किसी अन्य पॉसिक्स * निक्स पर
चलेगी

और वह विंडोज उदाहरण पावर शेल के साथ डिफ़ॉल्ट शेल के रूप में भी काम नहीं करेगा।
जूलियन नाइट

CopyWebpackPlugin के विपरीत, यह विकल्प फ़ाइल दिनांक रखता है। ओएस मुद्दा ओपन सोर्स के लिए समस्याग्रस्त हो सकता है, लेकिन छोटी टीमों के लिए आसानी से विंडोज बैश या रैपिंग xcopy cp.bat के साथ प्रबंधित किया जाता है।
एलियन टेक्नोलॉजी

2

मैं यहां भी फंस गया था। कॉपी-वेबपैक-प्लगइन ने मेरे लिए काम किया।

हालांकि, मेरे मामले में 'कॉपी-वेबपैक-प्लगइन' आवश्यक नहीं था (मैं बाद में सीखा)।

वेबपैक रूट पथ के
उदाहरण को अनदेखा करता है

<img src="/images/logo.png'>

इसलिए, रास्तों में 'कॉपी-वेबपैक-प्लगइन' का उपयोग '~' किए बिना इस काम को करने के लिए

<img src="~images/logo.png'>

'~' वेबपैक को 'चित्र' को एक मॉड्यूल मानने के लिए कहता है

ध्यान दें: आपको छवियों निर्देशिका की मूल निर्देशिका को जोड़ना पड़ सकता है

resolve: {
    modules: [
        'parent-directory of images',
        'node_modules'
    ]
}

यात्रा https://vuejs-templates.github.io/webpack/static.html


2

वेबपैक कॉन्फ़िगरेशन फ़ाइल (वेबपैक 2 में) आपको एक वादा श्रृंखला को निर्यात करने की अनुमति देती है, जब तक कि अंतिम चरण एक वेबपैक कॉन्फिगर वस्तु को वापस कर देता है। वादा कॉन्फ़िगरेशन डॉक्स देखें । वहां से:

webpack अब कॉन्फ़िगरेशन फ़ाइल से एक वादा लौटाने का समर्थन करता है। यह आपको कॉन्फ़िगरेशन फ़ाइल में async प्रसंस्करण करने की अनुमति देता है।

आप एक सरल पुनरावर्ती प्रतिलिपि फ़ंक्शन बना सकते हैं जो आपकी फ़ाइल की प्रतिलिपि बनाता है, और उसके बाद ही वेबपैक को ट्रिगर करता है। उदाहरण के लिए:

module.exports = function(){
    return copyTheFiles( inpath, outpath).then( result => {
        return { entry: "..." } // Etc etc
    } )
}

1

मान लें कि आपकी सभी स्थिर संपत्ति रूट स्तर पर एक फ़ोल्डर "स्थिर" में हैं और आप उन्हें सबफ़ोल्डर की संरचना को बनाए रखने वाले बिल्ड फ़ोल्डर में कॉपी करना चाहते हैं, फिर अपनी प्रविष्टि फ़ाइल में) बस डाल दें

//index.js or index.jsx

require.context("!!file?name=[path][name].[ext]&context=./static!../static/", true, /^\.\/.*\.*/);
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.