Как скопировать статические файлы для создания каталога с помощью Webpack?

Я пытаюсь перейти от Gulp до Webpack. В Gulp У меня есть задача, которая копирует все файлы и папки из /static/ до / build/. Как сделать то же самое с Webpack? Мне нужен плагин?

10 ответов


вам не нужно копировать вещи вокруг, webpack работает иначе, чем gulp. Webpack модуль пакетирования и все ссылки на ваши файлы будут включены. Вам просто нужно указать загрузчик для этого.

Итак, если вы пишете:

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

Webpack сначала попытается проанализировать ссылочный файл как JavaScript (потому что это значение по умолчанию). Конечно, это не сработает. Вот почему вам нужно указать загрузчик для этого типа файлов. The - или URL-адрес-погрузчик берем файл, кладем его в папку webpack (которая должна быть build в вашем случае) и верните хэшированный url для этого файла.

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

обычно загрузчики применяются через webpack config:

// webpack.config.js

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

конечно, вам нужно сначала установить загрузчик файлов, чтобы сделать эту работу.


требование активов с помощью модуля file-loader-это способ использования webpack (источник). Однако, если вам нужна большая гибкость или требуется более чистый интерфейс, вы также можете копировать статические файлы напрямую с помощью my copy-webpack-plugin (npm, Github). Для static to build пример:

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

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

Если вы хотите скопировать статические файлы, вы можете использовать загрузчик файлов следующим образом:

для html-файлов:

в webpack.конфиг.js:

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

в вашем js-файле:

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

./ static / относительно того, где находится ваш JS-файл.

Вы можете сделать то же самое с изображениями или любой другой. Контекст-это мощный метод исследования !!


выше предложения хороши. Но чтобы попытаться ответить на ваш вопрос напрямую, я бы предложил использовать cpy-cli в скрипте, определенном в вашем package.json.

в этом примере ожидает node где-то на вашем пути. Установить cpy-cli как зависимость развития:

npm install --save-dev cpy-cli

затем создайте пару файлов nodejs. Делать копию, а другой для отображения галочка и сообщение.

копировать.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');
}

галочку.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


одно преимущество, что вышеупомянутый копировать-webpack-плагин приносит, что не было объяснено раньше, это то, что все другие методы, упомянутые здесь, все еще связывают ресурсы в ваши файлы пакета (и требуют, чтобы вы "требовали" или "импортировали" их где-то). Если я просто хочу переместить некоторые изображения или некоторые частичные шаблоны, я не хочу загромождать мой файл пакета javascript бесполезными ссылками на них, я просто хочу, чтобы файлы были выпущены в нужном месте. Я не нашел любой другой способ сделать это в webpack. По общему признанию, это не то, для чего изначально был разработан webpack, но это определенно текущий случай использования. (@BreakDS я надеюсь, что это ответ на ваш вопрос - это только польза, если вы этого хотите)


скорее всего, вы должны использовать CopyWebpackPlugin, который был упомянут в ответе kevlened. Альтернативно для каких-то файлов, таких как .HTML-код или .в JSON вы также можете использовать raw-loader или JSON-loader. Установите его через npm install -D raw-loader и тогда вам нужно только добавить еще один загрузчик в наш .

как:

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

Примечание: перезапустите webpack-dev-server, чтобы изменения конфигурации вступили в силу.

и теперь вы можете требовать html-файлы с использованием относительных путей, это делает его гораздо проще перемещать папки вокруг.

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

вы можете написать bash в своем пакете.в JSON:

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

Я тоже застрял здесь. copy-webpack-плагин работал для меня.

однако "копировать-webpack-plugin" не был необходим в моем случае (я узнал позже).

webpack игнорирует корневые пути
пример

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

Следовательно, чтобы сделать эту работу без использования 'copy-webpack-plugin' использовать '~' в пути

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

' ~ 'говорит webpack рассматривать "изображения" как модуль

Примечание.: возможно, вам придется добавить родительский каталог каталог изображений в

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

посетить https://vuejs-templates.github.io/webpack/static.html


файл конфигурации webpack (в webpack 2) позволяет экспортировать цепочку обещаний, если последний шаг возвращает объект конфигурации webpack. см. документы конфигурации promise. Оттуда:

webpack теперь поддерживает возврат обещания из файла конфигурации. Это позволяет выполнять асинхронную обработку в конфигурационном файле.

вы можете создать простую рекурсивную функцию копирования, которая копирует ваш файл, и только после этого запускает webpack. Например:

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

допустим, все ваши статические активы находятся в папке "static" на корневом уровне, и вы хотите скопировать их в папку сборки, поддерживая структуру подпапки, затем в вашем файле ввода) просто поместите

//index.js or index.jsx

require.context("!!file?name=[path][name].[ext]&context=./static!../static/", true, /^\.\/.*\.*/);