Vue + Webpack: исключить config.js из упакованных работ, но он не загружается - PullRequest
3 голосов
/ 05 апреля 2019

Что я хочу:

В моем проекте Vue при выполнении vue run build все упаковывается (webpack) в каталог dist.

Я мог бы развернуть весь этот пакет на тестовом сервере, но поскольку тестовому серверу нужен другой набор учетных данных (для базы данных и т. Д.), Один файл, а именно config.js, должен быть разным в каждой среде.

Моя стратегия:

  • исключить config.js из упаковки в приложение.12314 ... js bundle
  • определить config.js как испущенный без изменений в виде файла (через file-loader) веб-пакета

Что я сделал:

В файлах компонентов Vue, для которых требуются данные конфигурации, конфигурация включается через:

<script>
  import config from '@/config/config.js';
</script>

Я создал файл vue.config.js для изменения настроек веб-пакета по умолчанию, например:

const path = require("path");

// vue.config.js
module.exports = {
  publicPath: '/',
  configureWebpack: {
    module: {
      rules: [
        {
          test: /config.*config\.js$/,
          use: [
            {
              // exclude config file from being packed. The config file should simply reside as a plain file on the
              // file system, since it must be replaced with the target environoment specific config file on the server,
              // e.g. for setting the correct database connection
              loader: 'file-loader',
              options: {
                name: 'config/config.js'
              },
            }
          ]
        }
      ]
    }
  }
}

То, что я ожидал:

  • config.js будет отправлено в виде простого файла, а не в комплекте => dist папка будет содержать в комплекте app....js файл и отдельный config.js файл
  • Я могу развернуть содержимое папки dist на тестовом сервере, и сгенерированный код позаботится о загрузке config.js, чтобы компоненты могли использовать данные конфигурации

Проблема:

Конечно, config.js теперь отправляется в виде файла, поэтому моя папка dist выглядит следующим образом:

.
├── config
│   └── config.js
├── css
│   ├── app.eb377513.css
│   └── chunk-vendors.2da46af1.css
├── favicon.png
├── index.html
└── js
    ├── app.724607ed.js
    ├── app.724607ed.js.map
    ├── chunk-vendors.426dad42.js
    └── chunk-vendors.426dad42.js.map

Как видите, отдельный файл config.js! Весь другой код JS включен в app.724607ed.js. Пока все хорошо.

Однако приложение на тестовом сервере будет не загружать config.js, поэтому каждый компонент, который пытается использовать в нем переменные, завершается ошибкой.

Я заметил, что в инструментах разработчика Chrome нет сетевого трафика для config.js. По-видимому, код веб-пакета не пытается на самом деле загрузить файл из файловой системы. Я ожидал, что это произойдет автоматически.

  1. что я делаю не так, что мне не хватает?
  2. это лучший способ исключить файл конфигурации из упаковки?

1 Ответ

1 голос
/ 09 апреля 2019

Очевидно, file-loader Webpack выдает файл отдельно (хорошо), но не добавляет код для загрузки его в веб-приложение (плохо). Я предполагал, что file-loader позаботится о вставке правильного тега <script> в файл index.html, чтобы:

  • будет загружен отдельно выпущенный config.js файл
  • на стороне разработчика, синтаксис для использования config.js такой же, как и для других (упакованных) артефактов, например:

(в файле компонента Vue:)

<script>
    import backend from '@/utils/backend.js'; // <-- normal way of requiring modules in Vue component
    import config from '@/config/config.js'; // <-- would work the same, but actually will load emitted file
</script>

К сожалению, похоже, я ошибался. Поскольку Webpack не заботится о загрузке файла в веб-приложение, я переключаюсь на ручной способ, например:

Шаг 1: выбросить в отдельный файл

Это важно, поскольку я хочу, чтобы файл config.js был отдельным (не упакованным и не уменьшенным вместе с остальной частью приложения Vue). Я уже описывал, как это сделать в вопросе (определите отдельное правило для config.js и используйте для него file-loader).

Шаг 2: позаботьтесь о загрузке файла конфигурации в веб-приложение

Поскольку file-loader не добавляет код загрузки, сделайте это вручную. В index.html вставить следующую строку:

<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <link rel="icon" href="<%= BASE_URL %>favicon.png">
    <script type="text/javascript" src="config/config.js" ></script> <-------- insert this line!
    <title>replayer-gui4</title>
</head>

Шаг 3: измените config.js на совместимый с прежним методом импорта (без модуля ES2015)

Теперь синтаксис commonJS больше не жизнеспособен, поскольку браузер должен загружать config.js. И я не уверен, как смешать загрузку модуля типа ES2015 (с собственным синтаксисом import) с кодом Webpack (который заменит все import с кодом загрузки Webpack). Поэтому я решил переключиться на унаследованный метод: пусть config.js просто зарегистрирует глобальную (чёрт!) Переменную, как в старые времена:

var config = (() => {
    return {
        databaseCredentials: ...
    };
})();

Следовательно, в каждом модуле Vue, использующем параметры конфигурации, адаптируйте код «import» - просто удалите импорт, потому что переменная config в любом случае будет доступна глобально (после наших изменений в config.js на этом шаге):

<script>
    // import config from '@/config/config.js'; // <-- commented out - or just REMOVE this line
</script>

Шаг 4: Запустить Webpack для рассмотрения config.js на всех

Единственное предостережение в настоящее время состоит в том, что, поскольку config.js никогда не упоминается в файле Javascript в операторе import, Webpack не "найдет" файл и никогда не примет его во внимание. Это означает, что config.js также никогда не будет излучаться.

Итак, заставить Webpack справиться с этим, в App.vue:

<script>
    import configDummy from '@/config/config.js';
</script>

Обратите внимание, что мы никогда не используем ссылку configDummy (переменную), просто Webpack находит ее и применяет свои правила к файлу. Правило в этом случае будет следующим: вывести его в виде отдельного файла в папке dist (т.е. создать файл dist/config/config.js)

Вот и все! Мы использовали file-loader Webpack, так что config.js не минимизируется и не включается в комплект приложений, а хранится в отдельном файле. Далее мы позаботились о загрузке через index.html, что означает, что настройки конфигурации доступны глобально.

Что мне не нравится в этом решении, так это то, что хорошая методика с import методами повреждена для этого специального файла. Но я не нашел простого решения, которое бы заставило Webpack позаботиться об этом.

Если у кого-то есть предложение, я был бы рад услышать!

Обновление 09.04.2019: Нет, это НЕ идеальное решение. Это работает для упаковки / развертывания (часть npm run build), но не для сервера разработки (часть npm run serve). Чтобы сервер dev работал, мне нужно было скопировать config.js в путь public/config/config.js, чтобы сервер dev мог найти его в том месте, о котором говорит index.html, то есть config/config.js (это решено относительно файла index.html).

Итак, еще раз: это работает, но неуклюже. И мне не нравится это решение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...