[Новичок] Руководство по интеграции Vue.js + Node.js(koa)

Vue.js Webpack

вебпак Дафа хороший

Webpack — это хорошо известный инструмент для разработки переднего плана. Он может создавать среду разработки, включающую горячие обновления, а также может генерировать сжатый код рабочей среды. Он также обладает гибкой масштабируемостью и богатой экологической средой. Но и его недостаток тоже весьма очевиден, то есть элементов конфигурации много и они сложные, достаточно вынуть определенный элемент конфигурации (например,rules,plugins,devtoolи т. д.) достаточно, чтобы написать статью, объясняющую его использование N, что вызывает большую путаницу у новичков. Vue.js (далее Vue) в основном построен с использованием веб-пакета, что косвенно оставляет эту проблему новичкам во Vue. Но будь то Vue или webpack, на самом деле, все они знают суть проблемы конфигурации, поэтому они тоже думают о своих способах решения этой проблемы, давайте взглянем на их старания.

Vue cli 2.x — готовая конфигурация

Давным-давно мы хотели инициализировать проект Vue, обычно предоставляемый vue-cli.vue initCommand (это также версия v2 Vue cli, далее именуемая Vue cli 2.x). И обычно некоторые относительно крупномасштабные проекты будут использоватьvue init webpack my-projectЧтобы использовать шаблон веб-пакета, возникает проблема конфигурации, упомянутая выше.

Чтобы решить эту проблему, подход Vue заключается в предоставлении готовой конфигурации, т. е. черезvue initВ выходящем проекте огромное количество конфигурационных файлов, сгенерированных по умолчанию, скриншоты такие:

Vue cli 2 build 目录

Гарантированно работает из коробки, но раз захочешь модифицировать, это равносильно входу в черный ящик, а разработчики вздыхают и вздыхают по поводу кучи файлов и кучи JSON.

webpack 4 — сильно упрощенная конфигурация

Также прошел год с тех пор, как был выпущен webpack 4, и одно из его основных изменений заключается в значительном упрощении конфигурации. это добавляетmode, сделайте некоторую очевидную встроенную конфигурацию. Так напримерNoEmitOnErrorsPlugin(), UglifyJSPlugin()Вам больше не нужно писать, это для субподрядаCommonsChunkPlugin()Также сжато в элемент конфигурацииoptimization.splitChunks, и есть значения по умолчанию, которые подходят для большинства ситуаций.

Говорят, что размер кода, созданного webpack 4, еще меньше, поэтому очевидно, что это обновление необходимо.

Vue cli 3.x — обновленный веб-пакет, также появились плагины

Около полугода назад Vue cli выпустила версию v3, которая также является подрывным обновлением. уменьшает ядро ​​до@vue/cli, превратил вебпак в@vue/cli-service, абстрагируя другие вещи в «плагины». Эти плагины включают babel, eslint, Vuex, Unit Testing и другие, а также позволяют писать и публиковать пользовательские записи. Я не буду вводить здесь использование и экологию Vue cli 3.x, но по результатам, теперь черезvue createСозданный проект Vue стал намного чище.

Vue cli 3 目录

Так в чем теперь вопрос?

Если мы просто разрабатываем интерфейсный проект Vue, webpack-dev-server может помочь нам запустить сервер nodejs и поддерживать горячую загрузку, что очень полезно. Но что, если мы хотим разработать полноценный проект nodejs + Vue?Невозможно, чтобы оба запускались на одном и том же порту.. Тогда все, что мы можем сделать, это заставить nodejs запускаться на порту A и позволить Vue (webpack-dev-server) запускаться на порту B. Если Vue необходимо отправить запрос на доступ к API, предоставляемому nodejs, он также столкнется с междоменными проблемами.Хотя это можно решить, настроив прокси, это все еще очень громоздко.По сути, это front-end и back-end целого проекта, для их запуска мы должны использовать одну команду, один порт.

Помимо Vue, такие требования на самом деле поддерживаются самим веб-пакетом. Потому что он предоставляет промежуточное ПО webpack-dev в дополнение к webpack-dev-server. Он также интегрирует функцию горячей загрузки в виде экспресс-промежуточного программного обеспечения. Итак, если наш nodejs использует экспресс в качестве сервисной инфраструктуры, мы можем использоватьapp.useВнедряя это промежуточное ПО таким образом, вы можете добиться их интеграции.

Вернемся к Vuecli 3. это проходитvue-cli-serviceкоманду, оберните webpack и webpack-dev-server, чтобы пользователи не могли видеть файл конфигурации, и достигните цели простоты. Но по сути файл конфигурации все еще существует, просто он перемещен вnode_modules/@vue/cli-service/webpack.config.jsВот и все. Конечно, для индивидуальных потребностей он также поддерживает пользователей для настройки объектов (configureWebpack) или цепочка (chainWebpack) двумя косвенными способами, но больше не дает возможность напрямую изменить файл конфигурации.

Но фатальным является то, что даже если он предоставляет достаточно способов изменить конфигурацию,Но он не может превратить webpack-dev-server в webpack-dev-middleware.. Это означает, что часть Vue, созданная с помощью Vue cli 3, и часть nodejs (express) не могут быть объединены.

Как с этим бороться?

Сказав так много, на самом деле это проблема, с которой я недавно столкнулся, и идея анализа проблемы. Из-за того, что Vue cli 3 представляет собой черный ящик, мы больше не можем его использовать (возможно, будет обновление для решения этой проблемы, по крайней мере, не сейчас). И использование Vue cli 2 также сбивает с толку, потому что он имеет встроенный webpack 3 и множество файлов конфигурации. Глядя на это таким образом, единственный оставшийся путьИспользуйте и настройте webpack 4 самостоятельноНу, вот о чем эта статья.

стек технологий

часть nodejs

В настоящее время основным веб-фреймворком для создания части nodejs являетсяexpress, не говоря уже о том, насколько элегантен его синтаксис, насколько широко он используется и т. д., основная причина в том, что только что упомянутое ПО webpack-dev-middleware является экспресс-посредником, поэтому их можно легко связать.

К сожалению, в моем реальном проекте я использовалkoaкак мой фреймворк nodejs. На самом деле, я не могу сказать, где это лучше, чем экспресс, и это не тема этой статьи. Это может быть для первых пользователей, или для унификации стека технологий команды, или для других совпадений.Во ​​всяком случае, я использовал его, и я не осознавал эту проблему интеграции в начале, пока не обнаружил webpack-dev- middleware и koa Это несовместимо, и у меня в сердце есть след сожаления... Конечно, это другая история.

В этой статье в качестве эталона используется koa. Если вы используете экспресс, это в основном то же самое и проще.

Vue-раздел

Vue особо нечего сказать, только одна версия, не существует экспресс/коа/других опций. Просто здесь я использовал не SSR, а обычный SPA-проект (одностраничное приложение, фронтенд-рендеринг).

Структура каталогов

Поскольку это комбинация двух проектов, всегда возникает проблема с расположением структуры каталогов. Я не буду здесь говорить о том, как должен быть организован каждый проект, это вопрос самого Vue/koa и вопрос личных предпочтений. То, о чем я хочу поговорить, это организация между ними, которая представляет собой не что иное, как следующие 3 типа: (на самом деле это также вопрос личных предпочтений, мнения различаются, здесь просто унифицированное выражение, чтобы избежать последующей путаницы)

Front-end и back-end проекты на следующих снимках экрана — все независимые проекты, то есть проекты до интеграции, которые можно запускать отдельно, поэтому вы видите две копии package.json и package-lock.json.

Back-end проект — это база, а front-end проект — это подкаталог

За исключением каталога vue в красной рамке, все остальное — это код nodejs. И поскольку я просто показываю, код nodejs на самом деле содержит только два index.js, общедоступный каталог и два package.json. Фактический проект nodejs должен иметь больше кода, такого как действия (отделение обработки каждого маршрута в каталог), промежуточное ПО (промежуточное ПО для всех маршрутов) и т. д.

Идея такого расположения состоит в том, чтобы думать, что интерфейс является частью всего проекта (часть отображения страницы), поэтому Vue размещается в отдельном каталоге.Я использую эту структуру.

Интерфейсный проект является базовым, а внутренний проект является подкаталогом.

Это противоположно предыдущему, красный прямоугольник — это внутренний код. Причина такого расположения может заключаться в том, что мы являемся разработчиками внешнего интерфейса, поэтому код внешнего интерфейса находится в основном месте, а API, предоставляемый серверной частью, помогает выполнять код Vue.

Нейтральный, никого не одобряющий

Прочитав первые два, я, естественно, могу подумать о третьем методе. Но я думаю, что этот метод не о чем беспокоиться, потому что согласно требованиям npm, package.json должен быть помещен в корневую директорию, поэтому на самом деле это скорее вредно, чем полезно, чтобы полностью разделить эти два и относиться к ним справедливо ( такие как различные типы Пути вызова будут иметь несколько слоев), подходит для пациентов с обсессивно-компульсивным расстройством.

Модернизация части Vue

Точки преобразования части Vue в основном:

  1. package.json объединяется с package.json в корневом каталоге (nodejs). В основном это зависимости (dependencyиdevDependency) и выполните команду (scripts) в двух частях. остальное какbrowserslist, engineДля полей, которые может использовать Babel, поскольку код nodejs не нуждается в Babel, его можно копировать напрямую, и нет никакого слияния.

  2. написатьwebpack.config.js. (Поскольку Vue cli 3 автоматически генерируется и скрывается, вам нужно написать это самостоятельно)

Подробнее см. ниже.

Пакет Fusion.json

упоминалось ранее, какbrowserslist, engineПоля, используемые babel и т. д., не нужны на стороне nodejs, поэтому их можно просто скопировать. Это зависимости и команды, которые требуют мозга.

С точки зрения зависимостей, на самом деле, зависимости, общие для передней и задней части, в основном не существуют, поэтому на самом деле это простая копия. Обратите внимание, что что-то вродеvue, vue-router, webpack, webpack-cliподождите всеdevDependency, вместоdependency. очень нужно поставитьdependencyДа собственно только@babel/runtimeэтот (потому что с помощьюplugin-transform-runtime).

Что касается команд, две необходимые команды для самого Vue — это «запустить среду разработки» и «сборка» (опционально есть тесты, которые я здесь обсуждать не буду). Поскольку среда разработки должна быть интегрирована с nodejs, мы помещаем это в часть nodejs. Остальное - команда сборки, нормальная работа - установкаNODE_ENVзаproductionДавайте добавим webpack в ситуацию с онлайн-сборкой. Также стоит отметить, что поскольку package.json и webpack.config.js теперь находятся не в одном каталоге уровня, вам необходимо указать дополнительные каталоги.Команды выглядят следующим образом: (cross-envэто очень полезный инструмент для установки переменных среды на разных платформах)

{
  "scripts": {
    "build": "cross-env NODE_ENV=production webpack --config vue/webpack.config.js"
  }
}

Напишите webpack.config.js

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

webpack.config.js по сути является конфигурационным файлом, который возвращает JSON, и мы будем использовать в нем несколько ключей. Если вы хотите узнать все элементы конфигурации веб-пакета, вы можете просмотретьКитайский сайт для webpackвводить. Кроме того, если вы не хотите просматривать его по разделам, вы можетездесьНайдите полный файл webpack.config.js.

mode

Новые элементы конфигурации в webpack 4, общие необязательные значения'production'и'development'. Здесь мы базируемсяprocess.env.NODE_ENVдля определения стоимости.

let isProd = process.env.NODE_ENV === 'production'

module.exports = {
  mode: isProd ? 'production' : 'development'
}

entry

Определяет точку входа для webpack. Нам нужно установить запись в JS, который создал экземпляр Vue, например.vue/src/main.js.

{
  entry: {
    "app": [path.resolve(__dirname, './src/main.js')]
  }
}

output

Определяет конфигурацию вывода для webpack. В состоянии разработки webpack-dev-middleware (далее wdm) на самом деле не генерирует этотdistКаталог, это через файловую систему в памяти, файлы вывода в память. Таким образом, этот каталог является просто идентификатором.

{
  output: {
    filename: '[name].[hash:8].js',
    path: isProd ? resolvePath('../vue-dist') : resolvePath('dist'),
    publicPath: '/'
  }
}

resolve

В основном определяют две вещи: обработка веб-пакетовimportпорядок суффиксов добавляется автоматически, а псевдонимы для быстрого доступа.

{
  resolve: {
    extensions: ['.js', '.vue', '.json'],
    alias: {
      'vue$': 'vue/dist/vue.esm.js',
      '@': resolvePath('src'),
    }
  }
}

модуль (выделено)

moduleВ webpack в основном определяется, как обрабатывать различные типы модулей в проекте. Здесь мы используем наиболее распространенный метод настройки, который заключается в том, чтобы сообщить веб-пакету, какой файл суффикса использовать с каким типом загрузчика.

{
  module: {
    rules: [
      {
        test: /\.vue$/,
        loader: 'vue-loader'
      },
      {
        test: /\.js?$/,
        loader: 'babel-loader',
        exclude: file => (
          /node_modules/.test(file) && !/\.vue\.js/.test(file)
        )
      },
      {
        test: /\.less$/,
        use: [
          isProd ? MiniCssExtractPlugin.loader : 'vue-style-loader',
          'css-loader',
          'less-loader'
        ]
      },
      {
        test: /\.css$/,
        use: [
          isProd ? MiniCssExtractPlugin.loader : 'vue-style-loader',
          'css-loader'
        ]
      }
    ]
  }
}

Приведенная выше конфигурация настраивает 4 метода обработки файлов, а именно:

  1. /\.vue$/

    Для обработки файлов Vue используйте специально предоставленный Vue.vue-loader. Что делает этот процессорпоместите Vue внутрь<script>и<style> детали изолируются, чтобы их можно было в дальнейшем обрабатывать отдельно по следующим правилам. иначе.vueфайл недоступен.jsили.cssпотока обработки. Также если<style>имеютlangсвойства, вы также можете ввести, например..less, .stylи другие процедуры обработки.

    Также требуются специализированные плагиныVueLoaderPlugin(), вы можете увидеть это позже, не пропустите.

  2. /\.js?$/

    Он якобы обрабатывается с суффиксом.jsфайл, но по сути он также используется здесь для работы с Vue внутри<script>Содержание. Здесь мы используемbabel-loaderПреобразуйте текст высокого уровня в коде в текст, совместимый с браузерами более ранних версий. Использование определенных правил перевода.babelrcконфигурация файла. Здесь также игнорируетсяnode_modules(Поскольку другие пакеты уже были перекодированы при выпуске, нет необходимости тратить дополнительное время). Но убедитесь,node_modulesВ мономере файл Vue все еще участвует в переводе, которыйОфициальная документация Vueрекомендуемая орфография.

  3. /\.less$/

    Я меньше использую препроцессор стилей в своем проекте, поэтому в каждом файле Vue, который я использую<style lang="less">. так черезvue-loader, вы можете позволить нескольким загрузчикам, настроенным в этом правиле, обрабатывать стили в файле Vue. Что эти загрузчики делают соответственно:

    1. vue-style-loader

      положить стиль с<style>Форма тегов вставляется в шапку страницы,Используется только в разработке.

      это иstyle-loaderРазница не большая, но так какОфициальная документация VueРекомендуется использовать это, так что давайте использовать это.

    2. mini-css-extract-pluginгрузчик

      Извлеките стили в отдельный файл css и<head>на этикетке<link rel="stylesheet">способ ссылки, заменяющий оригинальный webpack 3.xextract-text-webpack-plugin,Только для производства.

      Его также нужно добавить в плагинMiniCssExtractPlugin()для использования в сочетании.

    3. css-loader

      Поддержка загрузки ресурсов неявными средствами. Например, если написать в файл JSimport 'style.css', или пропишите в файле стилейurl('image.png'),проходить черезcss-loaderможно поставитьstyle.cssиimage.pngвнедряются в процесс обработки webpack. Таким образом, все загрузчики для css могут справиться с этим.style.css, в то время как загрузчик для всех изображений (например, тот, который автоматически конвертируется в base64, если размер мал)url-loader) можно обрабатыватьimage.png.

    4. less-loader

      Используйте загрузчик, который должен загрузить препроцессор less, чтобы преобразовать синтаксис less в обычный синтаксис css.

      В основном каждый препроцессор имеет соответствующий загрузчик, напримерstylus-loader, sass-loaderИ так далее, его можно использовать по необходимости.

  4. /\.css$/

    и.jsПравила аналогичны, это правило может быть применено к обоим.cssсуффикс-файл и в Vue<style>(и не писалlangчасть.

плагины (выделено)

Плагины похожи на правила, и они также обрабатывают ресурсы, загруженные в webpack. Однако, в отличие от правил, он не решает, входить или нет с обычным (в основном суффиксным именем), а определяет, какие из них обрабатывать через JS-метод написания самого плагина после ввода всех, поэтому он более гибкий .

Как упоминалось ранее, некоторые функции требуют использования загрузчика и плагинов, поэтому их также необходимо объявить здесь, напримерVueLoaderPlugin()иMiniCssExtractPlugin().

В нашем проекте плагины разделены на две категории. Одна категория используется вне зависимости от среды (разработка или производство), в этой категории 2 категории:

{
  "plugins": [
    // 和 vue-loader 配合使用
    new VueLoader(),

    // 输出 index.html 到 output
    new HtmlwebpackPlugin({
      template: resolvePath('index.html')
    })
  ]
}

Другой тип используется только в производственной среде, и их тоже 2:

if (isProd) {
  webpackConfig.plugins.push(
    // 每次 build 清空 output 目录
    new CleanWebpackPlugin(resolvePath('../vue-dist'))
  )
  webpackConfig.plugins.push(
    // 分离单独的 CSS 文件到 output,和 MiniCssExtractPlugin.loader 配合使用
    new MiniCssExtractPlugin({
      filename: 'style.css',
    })
  )
}

optimization

оптимизация — это новый элемент конфигурации в веб-пакете 4, который в основном касается различных оптимизаций в производственной среде (таких как сжатие, извлечение общего кода и т. д.), поэтому большинство оптимизаций находятся вmode === 'production'будет использоваться. Здесь мы используем только одну из его функций, а именно субподряд.new webpack.optimize.CommonChunkPlugin(), теперь вам нужно только настроить его, и способ настройки также очень прост:

{
  optimization: {
    splitChunks: {
      chunks: 'all'
    }
  }
}

Таким образом, изnode_modulesВходящий код будет упакован вместе и назван какvendors~app.[hash].js, который может содержать Vue, Vuex, Vue Router и другой сторонний код. Эти коды не очень часто изменяются, поэтому независимое и долгосрочное принудительное кэширование может значительно ускорить доступ к сайту.

Взгляните на скомпилированный продукт

запустивnpm run build, может позвонитьwebpack-cliдля запуска файла конфигурации, который вы только что написали. После успешной компиляции в корневом каталоге будет сгенерирован файлvue-distкаталог, в нем хранится следующее содержимое: (Если маршрутизация Vue загружена лениво, то естьconst XXX = () => import('@/XXX.vue'), файл будет разбит по маршруту, так что количество будет больше)

vue-dist

всего 4 файла

  1. index.htmlХранит уникальную запись HTML, которая содержит ссылки на различные файлы JS и CSS и определяет узлы-контейнеры. После запуска со статическим сервером может выполняться внешний рендеринг за счет выполнения JS.

  2. style.cssХраните все стили. Эти стили взяты из каждого файла Vue.<style lang="less">Части были извлечены и объединены.

  3. app.[hash].jsхранить всенастроитьJS, т.е. на файл Vue<script>часть, а такжеapp.js, router.js, store.jsкод и т. д.

  4. vendors~app.[hash].jsКак указано выше, хранить всебиблиотека классовJS, например vue-router, код самого vuex.

Для nodejs все, о чем вам нужно заботиться, этоindex.htmlВсе, остальные 3 будут им импортированы. Итак, давайте посмотрим, как преобразовать часть nodejs дальше.

Модернизация nodejs (koa) часть

Основные моменты, которые нам нужно преобразовать в части коа:

  1. package.json

    Стандартная конфигурация проектов nodejs, запись зависимостей, скриптов, информации о проекте и т.д.Нам нужно объединить здесь с package.json на стороне Vue, особенноnpm run devОбъединение скриптов.

  2. index.js

    Ввод кода nodejs через командуnode index.jsЗапустите весь проект. Здесь можно прописать правила роутинга, прописать промежуточное ПО, прописать wdm и т.д. Большая часть логики здесь.

    Поскольку среда разработки и рабочая среда ведут себя по-разному (например, для разработки требуется wdm, а для производства нет), его можно разделить на два файла (index.dev.jsиindex.prod.js), или можно судить по переменным среды в файле, которые варьируются от человека к человеку.

    Хотя здесь можно написать правила маршрутизации и промежуточное ПО koa, обычно, если это небольшой проект, обработка маршрутизации и промежуточное ПО будут разделены на отдельные компоненты.actionsиmiddlewaresКаталоги хранятся отдельно (начало имени зависит от ваших предпочтений). Файлы конфигурации (такие как настройка номера порта запуска) также обычно создаются независимо.config.jsилиconfigсодержание. другой напримерutilКаталоги и т. д. также создаются по запросу.

    Здесь нам нужно унифицировать переднюю и заднюю маршрутизацию и использовать wdm и т. д.

package.json

Как упоминалось в package.json «Renovation of Vue», зависимости проекта Vue напрямую копируются во внешний package.json, а дополнительныйnpm run buildЗаказ. Здесь будут перечислены еще две команды для удовлетворения самых основных потребностей.

Чтобы различать запущенную среду, я поставилindex.jsразобран дляindex.dev.jsиindex.prod.js. Как упоминалось выше, вы также можете использоватьprocess.env.NODE_ENVдля определения операционной среды.

Запустите сервер разработки

Регулярное обслуживание коа, как правило, мы проходимnode index.jsначать. Однако по умолчанию nodejs не загружается в горячем режиме, поэтому изменение кода nodejs требует перезапуска сервера, что вызывает проблемы. раньше я бы использовалchokidarМодуль прослушивает изменения в файловой системе и выполняется при наличии изменений.delete require.cache[path]реализовать простой механизм горячей загрузки. Но теперь для этого есть более удобный инструмент, а именноnodemon.

"nodemon -e js --ignore vue/ index.dev.js"

Он также очень прост в использовании,node index.jsзаменитьnodemon index.js, он будет отслеживать изменения всех файлов, выполняемых с этой записью, и автоматически перезапускаться. Но мы также используем здесь два дополнительных элемента конфигурации.-eУказывает указанное расширение, здесь мы слушаем только js.--ignoreУказывает игнорировать, потому чтоvue/В каталоге есть веб-пакет, который поможет нам выполнить горячую перезагрузку, поэтому его модификации можно игнорировать. Другие доступные элементы конфигурации могут ссылаться на nodemon.Домой.

Запустите сервер онлайн-среды

Это просто, непосредственно выполнитьnodeкоманда сделает. Итак, финальная часть скрипта выглядит следующим образом:

{
  "scripts": {
    "dev": "nodemon -e js --ignore vue/ index.dev.js",
    "build": "cross-env NODE_ENV=production webpack --config vue/webpack.config.js",
    "start": "node index.prod.js"
  }
}

index.js

Этот файл является начальной записью koa, и его общая структура выглядит следующим образом (я использую koa-router для управления маршрутизацией и перечисляю только самый простой скелет):

// 引用基本类库
const Koa = require('koa')
const Router = require('koa-router')
const koaStatic = require('koa-static')

// 初始化
const app = new Koa()
const router = new Router()

// 常规项目可能有中间件,即处理所有路由的逻辑,如验证登录,记录日志等等,这里省略

// 注册路由到 koa-router。
// 常规项目路由很多,应该独立到一个目录去一个个注册
router.get('/api/hello', ctx => {
  ctx.body = {message: 'Greeting from koa'}
})

// koa-router 以中间件的形式注册给 koa
// 就理解为固定写法
app.use(router.routes());
app.use(router.allowedMethods());
// 为 public 目录启动静态服务,可以放图片,字体等等。Vue 部分打包的资源在 vue-dist,不在这里。
app.use(koaStatic('public'));

// 实际项目可能端口还要写到配置文件,这里随意了
app.listen(8080)

Мы обсудим, как изменить этот файл с двух сторон: среды разработки и онлайн-среды.

среда разработки

Первый заключается в объединении внешнего и внутреннего маршрутов.

Сторона Vue использует режим маршрутизации истории, поэтому для взаимодействия ей нужны nodejs.ОфициальныйРекомендуетсяпромежуточное ПО connect-history-api-fallback, но это для экспресса. Я нашел промежуточное программное обеспечение для той же функциональности, используемой koa, под названиемkoa2-history-api-fallback.

Независимо от того, какое это промежуточное ПО, принцип один и тот же. Поскольку SPA генерирует толькоindex.html,следовательноВсе маршруты навигациидолжен быть направлен в этот файл, иначе например/user/indexТакой маршрут браузер найдет/user/index.htmlОчевидно, нельзя найти.

Поскольку то, что нужно Vue,Все маршруты навигации, очевидно, что его нельзя зарегистрировать до маршрута коа, иначе маршрут коа никогда не вступит в силу. Таким образом, порядок регистрации маршрута закономерен:Бэкенд, затем фронтэнд. Кроме того, упомянутый здесь маршрут навигации относится к первому запросу на запрос HTML, а запрос статических ресурсов не включен, поэтому, например, приведенный вышеpublicПорядок статических маршрутов и промежуточного программного обеспечения Vue не имеет значения.

Таким образом, часть маршрутизации после слияния, вероятно, выглядит так:

// 后端(koa)路由
// koa-router 的单个注册部分省略
app.use(router.routes());
app.use(router.allowedMethods());

// 前端(vue)路由
// 所有 navigate 请求重定向到 '/',因为 webpack-dev-middleware 只服务这个路由
app.use(history({
  htmlAcceptHeaders: ['text/html'],
  index: '/'
}));
app.use(koaStatic('public'));

Второй — начало проблемы, использование webpack-dev-middleware.

Подобно промежуточному программному обеспечению Vue, webpack-dev-middleware поддерживает только экспресс (все это показывает, что экология экспресса лучше), а затем я также нашел альтернативу версии koa, которая называетсяkoa-webpack.

Это не сложно использовать, а именно:

const koaWebpack = require('koa-webpack')
const webpackConfig = require('./vue/webpack.config.js')

// 注意这里是个异步,所以和其他 app.use 以及最终的 app.listen 必须在一起执行
// 可以使用 async/await 或者 Promise 保证这一点
koaWebpack({
  config: webpackConfig,
  devMiddleware: {
    stats: 'minimal'
  }
}).then(middleware => {
  app.use(middleware)
})

полныйindex.dev.jsможет просматриватьздесь.

онлайн-среда

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

Во-первых, в онлайн-среде не используется webpack-dev-middleware (koa-webpack), поэтому эта часть кода не нужна.

Во-вторых, поскольку весь встроенный код Vue находится в каталоге vue-dist, а запись HTML и другие нужные нам файлы JS и CSS находятся в нем, поэтому нам нужно добавить каталог vue-dist в статический сервис для доступа, и история. Цель отступления также изменилась следующим образом:

// 后端(koa)路由
// koa-router 的单个注册部分省略
app.use(router.routes());
app.use(router.allowedMethods());

// 前端(vue)路由
// 所有 navigate 请求重定向到 /vue-dist/index.html 这个文件,配合下面的 koaStatic('vue-dist'),这里只要填到 '/index.html' 即可。
app.use(history({
  htmlAcceptHeaders: ['text/html'],
  index: '/index.html'
}));
app.use(koaStatic('vue-dist'));
app.use(koaStatic('public'));

полныйindex.prod.jsможет просматриватьздесь.

Так много новичков в настройке все еще в замешательстве, что мне делать?

Пока мы это много обсуждали, не бойтесь, на самом деле есть только три важных момента, давайте подытожим:

  1. Нам нужно самим написать webpack.config.js для Vue, обрабатывать загрузчики, плагины и т. д.

  2. Нам нужно объединить два package.json передней и задней части, объединить зависимости двух сторон и написать три скрипта (dev, build, start)

  3. нам нужно изменитьindex.js, обрабатывать порядок маршрутизации и вызывать webpack-dev-middleware в среде разработки

Чтобы легко начать работу, я извлек бизнес-код из проекта и оставил скелет, который можно использовать в качестве стартового шаблона проекта Vue + koa, размещенный вeasonyq/vue-nodejs-template. Однако, думаю, нам все же следует освоить методы и принципы настройки, чтобы, если какая-то часть стека технологий изменится в будущем (например, выходит webpack 5), мы тоже могли изучить и модифицировать его сами, вместо того, чтобы давать приоритет решения задач каждый раз.Неважно, умеете ли вы бегать.

Пусть все мы идем гладко по переднему пути!