Webpack으로 디렉토리를 빌드하기 위해 정적 파일을 복사하는 방법은 무엇입니까?


330

에서 Gulp로 이동하려고 합니다 Webpack. 에서 Gulp나는 복사하는 모든 파일 및 폴더 작업이 / 정적 / 폴더 / 구축 / 폴더에 있습니다. 어떻게 Webpack합니까? 플러그인이 필요합니까?


2
Gulp는 이해하기에 좋습니다. 원하는 경우 gulpfile.js에서 webpack을 호출하십시오
Baryon Lee

Laravel Mix를 사용하는 경우 laravel.com/docs/5.8/mix#copying-files-and-directories 를 사용할 수 있습니다.
Ryan

답변:


179

당신은 주위에 물건을 복사 할 필요가 없습니다. Webpack은 모듈 번 들러이며 파일에서 참조하는 모든 것이 포함됩니다. 로더를 지정하기 만하면됩니다.

그래서 당신이 쓰는 경우 :

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

Webpack은 먼저 참조 파일을 JavaScript로 구문 분석하려고 시도합니다 (기본값이므로). 물론, 그것은 실패 할 것입니다. 따라서 해당 파일 형식에 대한 로더를 지정해야합니다. 파일 - 또는 URL 로더 예를 들면은, 참조 된 파일을 웹팩의 출력 폴더에 넣어 (수 있어야하는 build귀하의 경우) 해당 파일의 해시 URL을 반환합니다.

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

일반적으로 로더는 webpack 구성을 통해 적용됩니다.

// webpack.config.js

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

물론이 작업을 수행하려면 먼저 파일 로더를 설치해야합니다.


42
" 물론이 작업을 수행하려면 먼저 파일 로더를 설치해야합니다. "위에서 언급 한 "파일 로더"에 링크 하십시오 . 설치 및 사용 방법은 다음 과 같습니다 .
Nate

21
여전히 HTML 파일과 그 안의 모든 참조가로드되지 않는 문제가 있습니다.
kilianc

125
예, webpack 플러그인을 사용하려면 파일 로더, CSS 로더, 스타일 로더, URL 로더를 사용할 수 있습니다. 그런 다음 필요한 방식으로 구성 할 수 있습니다. 인터넷 검색 및 잠들지 않음 :) 또는 copy-webpack-plugin을 사용하여 작업을 완료 할 수 있습니다.
Kamil Tomšík

11
@ KamilTomšík 따라서 웹팩 플러그인을 피하기 위해 웹팩 플러그인을 사용해야합니까? (농담입니다. 요점을 알았습니다.)
Konrad Viltersten

12
좋아, 모든 이미지의 대부분은 CSS와 HTML에 있습니다. 따라서 require ( 'img.png')를 사용하여 JS 파일에 이러한 이미지가 모두 필요합니까? 해당 파일 로더와 함께 작동하게하려면? 정말 미친 짓입니다.
Rantiev

579

파일 로더 모듈을 사용하여 자산을 요구하는 것은 웹팩이 사용되는 방식입니다 ( source ). 그러나 더 큰 유연성이 필요하거나 더 깨끗한 인터페이스를 원한다면 my copy-webpack-plugin( npm , Github )를 사용하여 정적 파일을 직접 복사 할 수도 있습니다 . 예 staticbuild들어 :

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

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

11
전체 디렉토리 (예 : 정적 html 및 기타 상용구 이미지)를 복사 할 때 훨씬 간단합니다!
Arjun Mehta

6
트릭을 했어요, 고마워요 :) 아주 간단한 명령을 수행하려고 여러 번 실패한 후 파일 로더를 포기했습니다. 플러그인이 처음 작동했습니다.
arcseldon

3
@Yan 플러그인은 파일이 변경되면 파일을 다시 복사합니다 (dev-server 또는 webpack --watch). 복사하지 않은 경우 문제를 제기하십시오.
kevlened

2
나는 webpack을 처음 사용하지만 왜 파일 로더 / url-loader / img-loader ...를 복사하는 대신 사용해야합니까? 예를 들어 파일 로더로이를 수행하면 어떤 이점이 있습니까?
BreakDS

2
당신은 플러그인 작성자이기 때문에. 이 질문에 더 나은 속도는 없습니다. "copy-webpack-plugin"플러그인을 사용하면 소스 디렉토리에서 파일을 필터링하여 특정 파일 확장자가 ex 인 파일 만 복사 할 수 있습니다. ".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
copy-webpack-plugin 모듈보다이 방법을 선호합니다. 또한 웹팩 구성에서 "& context =. / app / static"을 사용하지 않고도 작동시킬 수있었습니다. require.context 줄만 필요했습니다.
Dave Landry

2
나는 이것을 시도하고 있지만 훌륭해 보이지만 하나의 작은 문제에 대해 내 index.html하위 디렉토리에 _(밑줄) 이라는 하위 디렉토리를 넣는 중 입니다.
kris

2
"JS 파일에"라고 말할 때 무슨 뜻입니까? JS 파일이 없으면 어떻게합니까?
evolutionxbox

물론. 입력 스크립트에서이 한 줄 main.jsstatic폴더 내의 모든 항목을 가져 오는 것입니다 .require.context("./static/", true, /^.*/);
Mario

2
이것은 깔끔한 해킹이지만 너무 많은 파일을 복사하면 메모리가 부족합니다.
Tom

18

앞에서 언급 하지 않은 앞에서 언급 한 copy-webpack-plugin 의 이점 중 하나 는 여기에 언급 된 다른 모든 방법이 여전히 리소스를 번들 파일에 번들링한다는 것입니다. 일부 이미지 또는 일부 템플릿 부분을 옮기고 싶다면 Javascript 번들 파일을 쓸모없는 참조로 어지럽히고 싶지 않고 파일이 올바른 위치에 방출되기를 원합니다. 웹팩에서 다른 방법을 찾지 못했습니다. 분명히 웹팩은 원래 설계된 것이 아니라 확실히 현재 사용 사례입니다. (@BreakDS이 질문에 대한 답변이 되었기를 바랍니다. 원하는 경우에만 도움이됩니다)


7

위의 제안이 좋습니다. 그러나 귀하의 질문에 직접 대답하려면에 cpy-cli정의 된 스크립트를 사용 하는 것이 좋습니다 package.json.

이 예제는 node당신의 어딘가에있을 것으로 기대 합니다. cpy-cli개발 종속성으로 설치하십시오 .

npm install --save-dev cpy-cli

그런 다음 두 개의 nodejs 파일을 작성하십시오. 하나는 복사를하고 다른 하나는 확인 표시와 메시지를 표시합니다.

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",
...

sript를 실행하려면

npm run copy


3
OP는 npm 스크립트를 사용하지 않고 웹팩 내에서 파일 이동을 수행하고 싶습니까?
William S

영업 이익이 내부의 웹팩를 해결하기 위해 원하는 경우에도, 그가 웹팩가 실행되는 자신의 빌드 스크립트에 추가 할 수 있도록, 그는 NPM을 통해 웹팩를 실행하는 것이 가능하다
제작 : Piro가 분석 재개 모니카 말한다

5

대부분의 경우 당신은 kevlened 답변에서 언급 된 CopyWebpackPlugin을 사용해야합니다. .html 또는 .json 과 같은 파일의 경우 raw-loader 또는 json-loader를 사용할 수도 있습니다. 그것을 통해 설치 npm install -D raw-loader한 다음 당신이해야 할 일은 webpack.config.js파일에 다른 로더를 추가하는 것 입니다.

처럼:

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

참고 : 구성 변경 사항을 적용하려면 webpack-dev-server를 다시 시작하십시오.

이제 상대 경로를 사용하여 html 파일이 필요할 수 있으므로 폴더를 훨씬 쉽게 옮길 수 있습니다.

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

5

방법 I 부하 정적 imagesfonts:

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작동 하도록 설치 하는 것을 잊지 마십시오 .


중복 파일 이름을 어떻게 처리합니까? 또는 새로운 출력 디렉토리에서 원래 경로를 유지하는 방법을 알고 있습니까?
cantuket 2012 년

프로젝트에서 동일한 확장자 이름을 가진 중복 파일 이름이 없어야합니다. 내용이 동일하다면 복제본을 유지하는 이유는 무엇입니까? 그렇지 않은 경우 내용에 따라 다르게 이름을 지정하십시오. 그래도 원래 경로에 물건을 보관하려면 왜 웹팩을 사용하겠습니까? JS 번역 만 원한다면 Babel이면 충분합니다.
RegarBoy

1
컴포넌트 기반 개발을 구현하는 경우 (주요 원칙 중 하나는 캡슐화이며,이 경우 정보 숨기기 ) , 언급 한 내용 중 어느 것도 적절하지 않습니다. 즉, 누군가가 프로그램에 새로운 컴포넌트를 추가 할 때, 이름이 다른 이미지가 있는지 확인할 필요 logo.png도없고 글로벌 충돌을 피하기 위해 둔하고 "희망스럽게"고유 한 파일 이름을 만들어야 할 필요가 없습니다. 우리가 CSS 모듈 을 사용하는 것과 같은 이유 입니다.
cantuket

1
이미지가 원래 경로와 파일 이름을 유지하기를 원하는 이유는 무엇입니까? 주로 소스 맵을 사용하는 것과 같은 이유와 SEO 도 디버깅 합니다. 어쨌든 내 질문에 대한 대답은 실제로 매우 간단했습니다 ... [path][name].[ext]특정 환경이나 사용 사례에 맞게이를 수정하기 위해 많은 유연성이 제공됩니다 ... file-loader
cantuket

1
우리는 귀하의 예를 변형하여 구현 했으므로 제공해 주셔서 감사합니다!
cantuket

3

package.json에 bash를 작성할 수 있습니다.

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

1
Windows에서는 cp 대신 xcopy를 사용하십시오."build": "webpack && xcopy images dist\\images\\ /S /Y && xcopy css dist\\css\\ /S /Y"
SebaGra

7
그렇다면 솔루션은 각 OS마다 다른 스크립트를 사용하는 것입니까?
Maciej Gurban

예, 저에게는 각 OS에 대한 스크립트가 허용됩니다 (리눅스의 스크립트가 Darwin 또는 다른 POSIX * nix에서 실행될 것이기 때문에 실제로 유닉스 / 비 유닉스입니다)
Victor Pudeyev

그리고 Windows 예제는 PowerShell에서도 기본 셸로 작동하지 않습니다.
Julian Knight

CopyWebpackPlugin과 달리이 옵션은 파일 날짜를 유지합니다. OS 문제는 오픈 소스에서 문제가 될 수 있지만 소규모 팀의 경우 Windows bash를 사용하거나 cp.bat로 xcopy를 래핑하여 쉽게 관리 할 수 ​​있습니다.
Alien Technology 15

2

나도 여기에 붙어 있었다. copy-webpack-plugin이 나를 위해 일했습니다.

그러나 필자의 경우 'copy-webpack-plugin'이 필요하지 않았습니다 (나중에 배웠습니다).

webpack은 루트 경로
를 무시합니다.

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

따라서 'copy-webpack-plugin'을 사용하지 않고이 작업을 수행하려면 경로에 '~'를 사용하십시오.

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

'~'는 '이미지'를 모듈로 고려하도록 웹팩에 지시합니다.

참고 : 이미지 디렉토리의 상위 디렉토리를 추가해야 할 수도 있습니다.

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

https://vuejs-templates.github.io/webpack/static.html 방문


2

webpack 구성 파일 (webpack 2에 있음)을 사용하면 마지막 단계에서 webpack 구성 객체를 반환하는 한 promise 체인을 내보낼 수 있습니다. 약속 구성 문서를 참조하십시오 . 거기에서:

webpack은 이제 구성 파일에서 Promise 반환을 지원합니다. 이를 통해 구성 파일에서 비동기 처리를 수행 할 수 있습니다.

파일을 복사하는 간단한 재귀 복사 기능을 만들 수 있으며 그 후에 만 ​​웹팩을 트리거 할 수 있습니다. 예 :

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, /^\.\/.*\.*/);
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.