Упаковки

Это последняя часть в этой серии по настройке проекта Vue с нуля с использованием Webpack 4, часть 1 доступна здесь, а часть 2 - здесь. Ниже я расскажу:

  1. Линтинг.
  2. Тестирование.
  3. Обработка статических активов.

И, основываясь на вопросе из предыдущей статьи, я также упомяну извлечение css.

Окончательный код доступен на гитхабе.

В комментарии к части 1 @ blacksonic86 предложил называть точку входа для нашего приложения index.js, а не app.js. Это имеет большой смысл, так как это значение по умолчанию в webpack 4, что означает, что мы можем удалить его из нашего webpack.config.dev.js.

На практике у меня часто бывает несколько точек входа, поскольку я использую эту конфигурацию для добавления полифилов для поддержки старых браузеров, таких как Internet Explorer, но в данном случае это изменение, о котором я должен был подумать. Изменение имени файла означает, что текущая конфигурация веб-пакета приведена ниже.

'use strict'
const webpack = require('webpack')
const { VueLoaderPlugin } = require('vue-loader')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
  mode: 'development',
  
  devServer: {
    hot: true,
    watchOptions: {
      poll: true
    }
  },  module: {
    rules: [
      {
        test: /\.vue$/,
        use: 'vue-loader'
      }, {
        test: /\.js$/,
        use: 'babel-loader'
      }, {
        test: /\.styl(us)?$/,
        use: [ 'vue-style-loader', 'css-loader', 'stylus-loader' ]
      }
    ]
  },
plugins: [
    new webpack.HotModuleReplacementPlugin(),
    new VueLoaderPlugin(),
    new HtmlWebpackPlugin({
      filename: 'index.html',
      template: 'index.html',
      inject: true
    }) 
  ]
}

Линтинг

Линтинг - это процесс применения статического анализа к вашей кодовой базе для выявления проблем или обеспечения соблюдения рекомендаций по стилю. Это очень полезно при работе с динамически типизированными языками, такими как javascript. ESLint - это стандартный линтер, он позволяет вам определять наборы правил для работы с вашей кодовой базой или использовать плагины для использования заранее определенного набора. Мы будем использовать плагин Vue eslint, чтобы обеспечить соблюдение рекомендуемых правил для приложения Vue.

Нам нужно установить несколько пакетов npm, чтобы включить линтинг:

npm install --save-dev eslint eslint-plugin-import eslint-plugin-node eslint-plugin-promise eslint-plugin-standard eslint-config-standard babel-eslint eslint-loader eslint-plugin-vue

Как только это будет сделано, нам нужно указать eslint, какие правила мы хотим использовать, создать файл с именем .eslintrc.js в корне проекта и добавить следующие настройки:

module.exports = {
  parserOptions: {
    parser: 'babel-eslint'
  },
  extends: [
    'plugin:vue/recommended',
    'standard'
  ],
  plugins: [
    'vue'
  ]
}

Здесь мы сообщаем eslint, что хотим использовать babel для синтаксического анализа нашего javascript, а затем применить стандартные правила линтинга и рекомендуемые правила из плагина vue.

Самый простой способ запустить ESLint - через скрипт npm. Добавьте это в package.json в разделе скриптов:

"lint": "eslint --ext .js,.vue src"

Мы запускаем ESLint для чего-либо в нашей папке src с расширением файла .js или .vue. Запустите это сейчас, и вы уже должны получить сообщение об ошибке.

Это указывает на эти строки в нашем index.js, у меня установлено расширение eslint для VSCode, поэтому, если я открою этот файл сейчас, я вижу еще один визуальный сигнал, что что-то не так.

Есть разные способы исправить это, например, мы можем экспортировать новый объект Vue, однако давайте скажем ESLint, что эта строка на самом деле в порядке, и мы хотим, чтобы она игнорировала ее. Добавьте этот комментарий непосредственно перед ошибочным кодом:

/* eslint-disable-next-line no-new */

Теперь, когда вы повторно запускаете наш lint-скрипт, он не должен сообщать об ошибках.

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

"lint:fix": "eslint --ext .js,.vue src --fix"

После того, как наш линтинг настроен на запуск по требованию, мы хотим изменить нашу сборку webpack, чтобы она запускалась автоматически. Для этого нам нужно установить загрузчик веб-пакетов:

npm install --save-dev eslint-loader

И измените конфигурацию нашего веб-пакета, чтобы добавить правило, связывающее наши файлы .js и .vue с загрузчиком ESLint:

{
  test: /\.(js|vue)$/,
  use: 'eslint-loader',
  enforce: 'pre'
}

Одно изменение этого правила по сравнению с другими, принудительное исполнение: «до». Это означает, что загрузчик ESLint является предварительным загрузчиком, он будет запускаться перед другими загрузчиками и применять правила линтинга до того, как загрузчик babel начнет обрабатывать javascript.

Статические активы

Статические ресурсы - это такие вещи, как изображения и видео, они не будут обрабатываться Webpack, но мы потребуем их скопировать в нашу папку dist, чтобы они были доступны для созданного приложения.

Для этого мы используем плагин copy-webpack-plugin. Следуя уже знакомому пути, нам нужно установить пакет:

npm install --save-dev copy-webpack-plugin

Затем в конфигурации нашего веб-пакета мы извлекаем плагин и добавляем его в наш раздел плагинов.

const CopyWebpackPlugin = require('copy-webpack-plugin')
const path = require('path')
function resolve (dir) {
  return path.join(__dirname, '..', dir)
}
plugins: [
  new CopyWebpackPlugin([{
    from: resolve('static/img'),
    to: resolve('dist/static/img'),
    toType: 'dir'
  }])
]

Это довольно просто, все изображения, которые мы помещаем в нашу папку static / img, будут скопированы в эквивалентную папку в нашей папке сборки dist.

Тестирование

Являясь частью экосистемы Vue, vue-test-utils является официальной библиотекой модульного тестирования для Vue.js. Он поддерживает несколько исполнителей тестов, неглубокий рендеринг, имитацию взаимодействия с пользователем, имитацию vuex и vue-router и синхронные обновления (устраняя необходимость вызова nextTick для запуска обновлений dom).

В этом примере я собираюсь использовать шутку для запуска тестов. Jest взят из facebook и тесно связан с React, однако он может адаптироваться к любой библиотеке или фреймворку Javascript, а также существует экосистема, специфичная для vue, позволяющая нам запускать наши тесты без каких-либо проблем.

Установим шутку:

npm install --save-dev jest babel-jest vue-jest jest-serializer-vue @vue/test-utils

Jest - это средство запуска тестов, vue-jest - это пакет для преобразования компонентов vue в правильный формат для jest, а jest-serializer-vue - это пакет, который поддерживает создание снимков компонентов vue. Тестирование моментальных снимков позволяет отрисовывать полную модель DOM, а затем выполнять сравнения, чтобы убедиться, что она не меняется.

Вместо отдельного файла конфигурации Jest настраивается из нашего package.json. Добавьте это в конец нашего json-объекта:

"jest": {
  "moduleFileExtensions": [
    "js",
    "vue"
  ],
  "moduleNameMapper": {
    "^@/(.*)$": "<rootDir>/src/$1"
  },
  "transform": {
    "^.+\\.js$": "<rootDir>/node_modules/babel-jest",
    ".*\\.(vue)$": "<rootDir>/node_modules/vue-jest"
  },
  "snapshotSerializers": [
    "<rootDir>/node_modules/jest-serializer-vue"
  ]
}

Пока мы находимся в package.json, давайте добавим скрипт для запуска наших тестов:

"test": "jest"

Нам нужно настроить babel для транспиляции наших тестов, добавьте это в файл .babelrc:

"env": {
  "test": {
    "presets": [
      ["env", { "targets": { "node": "current" }}]
    ]
  }
}

И расскажите ESLint о нашей тестовой среде, добавив это в файл .eslintrc.js:

env: {
  browser: true,
  node: true,
  mocha: true
},
globals: {
  expect: true
}

Теперь, когда шутка настроена, мы можем написать тест. Для простоты мы просто смонтируем наш компонент App и проверим, что он имеет класс «.center-content». По умолчанию Jest будет искать тесты в папке с именем __tests__, поэтому создайте ее в папке src и добавьте файл с именем App.spec.js.

Мы используем Vue test-utils для монтирования приложения, а затем запускаем простое ожидание для возвращенной оболочки.

Чтобы запустить этот тест, достаточно:

npm run test

Извлечение CSS

Об этом Ahsath спрашивал в комментариях к части 2. Это свидетельствует о темпах изменений в области веб-пакетов, которые за неделю, прошедшую с момента публикации, описали метод извлечения CSS в отдельный файл. полностью изменился. С выпуском vue-loader 15 MiniCssExtractPlugin стал стандартным способом извлечения CSS из однофайловых компонентов Vue.

Установите плагин из npm:

npm install --save-dev mini-css-extract-plugin

Добавьте его в плагины в нашем конфигурационном файле webpack:

const MiniCssExtractPlugin  = require('mini-css-extract-plugin')
.
.
plugins: [
  new MiniCssExtractPlugin({
    filename: 'main.css'
  })
]

И, наконец, настройте наш загрузчик стилуса для использования этого плагина для извлечения css и загрузчика vue для извлечения CSS из наших отдельных файловых компонентов:

module: {
  rules: [
    {
      test: /\.vue$/,
      use: 'vue-loader'
    }, {
      test: /\.styl(us)?$/,
      use: [
        MiniCssExtractPlugin.loader,
        'css-loader',
        'stylus-loader'
      ]
    }
  ]
}

Теперь, когда наше приложение построит, весь стилус будет извлечен и помещен в один файл css (main.css) в нашей папке dist. CSS с ограничением области видимости из наших однофайловых компонентов также будет включен, например:

Это все, ребята

Надеюсь, эти статьи были вам полезны. С приближением появления vue-cli 3 для них уже есть элемент устаревания, метод работы с webpack претерпит значительные изменения. Однако всегда будет важно знать, как эти вещи настроены под капотом, и нет лучшего способа сделать это, чем работать с нуля.