Научит вас инкапсулировать компоненты Vue, которые повторно используются в проектах.

Vue.js
Научит вас инкапсулировать компоненты Vue, которые повторно используются в проектах.

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

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

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

Общая ситуация с повторно используемыми компонентами

  • Повторное использование компонентов ограничено одним проектом
  • Одна разработка, n разиспользоватьсистема
  • Разделение проекта увеличивает проблему в геометрической прогрессии, и каждое исправление/изменение нужно синхронизировать n раз.
  • Зависимые библиотеки одноуровневых проектов могут быть похожими, но разными, или разница версий велика.
  • Различия в средах или версиях модульного тестирования также вызывают проблемы при повторном использовании компонентов.

Что касается различий одного и того же компонента в разных проектах, инкапсулируйте el-date-picker в element-ui с помощью вторичного пакета.DateRange.vueПример компонента:

Проект библиотека базовых компонентов Обнаруженные репрезентативные проблемы
A element-ui@v1.x
  • Результаты выбора показывают, что он реализован одним вводом в базовом dom, в отличие от последней версии библиотеки компонентов.
  • el-date-picker еще не поддерживает атрибут формата значения
B
C
D
E element-ui@v2.x
  • v-модель внутреннего компонента неправильно запускает обратный вызов, это необходимо исправить с помощью часов
  • В этих проектах необходимо добавить некоторые дополнительные стили
F

По разным причинам библиотеки пользовательского интерфейса, от которых зависят несколько проектов, похожи, но не одинаковы; размер проекта слишком велик, команда поддержки отличается и т. д., что делает практически невозможной унификацию базовой библиотеки компонентов~🐔 Ты такая красивая,Это так стыдно~

Как совместить точки обслуживания?

  • Для нескольких проектов в примере есть 6 точек обслуживания и рабочая нагрузка × 6
  • еслиОбъединение в единую библиотеку, то точка обслуживания становится 2, и нужно различать только разницу между библиотекой базовой версии
  • Для большинства более простых компонентов разные версии базовой библиотеки компонентов не будут вызывать различий, или для простых компонентов, которые вообще не ссылаются на библиотеку компонентов element-ui, точка обслуживания может быть напрямую уменьшена до 1.

Какие компоненты являются универсальными?

  • Достаточно абстрактный, не содержащий бизнес-логики или достаточно расширяемый
  • попробуй не включать$t,$routerи другие зависимости, связанные со средой проекта
  • Имеются юнит-тесты с достаточным покрытием
  • Иметь необходимую документацию или описать достаточно полную функциональность с помощью модульных тестов.
  • Желательно также предоставить рабочий пример

Опубликовать в нпм

В конкретном проекте достаточно обратиться к исходному коду компонента;

Один из подходов к общей библиотеке компонентов для проектов состоит в том, чтобы поддерживать в каждом проекте подмодуль, указывающий на исходный код библиотеки компонентов (git поддерево или подмодуль), но этот метод сложнее поддерживать, поэтому он обычно не используется.

Другой способ, к которому мы больше привыкли, — это прямое обращение к зарегистрированному имени компонента после его установки через npm (package.jsonсерединаname).

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

Основные шаги для публикации компонентов npm:

Зарегистрируйте пользователя на npmjs.com или через командную строку:

npm adduser

Подтвердите вход перед публикацией:

npm login

Вручную измените package.json перед публикацией или используйте командную строку для обновления номера версии проекта. Обратите внимание, что номер версии не может быть одинаковым для каждого выпуска:

npm version x.x.x

Выполнить выпуск:

npm publish

Откройте домашнюю страницу проекта прямо из командной строки, чтобы просмотреть:

npm home [name]

Дополнительные команды см. в официальной полной документации:docs.thathorseplus.com/handle-doc_door…

Следует также отметить, что правильная конфигурация в package.jsonrepositoryполе для отображения ссылки на репозиторий на домашней странице компонента npm.

Компоненты пакета с накопительным пакетом вместо веб-пакета

В этом примере в качестве инструмента упаковки выбран накопительный пакет:

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

Базовый набор конфигураций

Предположим, что структура библиотеки компонентов запланирована следующим образом:

├─.babelrc
├─.eslintignore
├─.eslintrc.js
├─.gitignore
├─CHANGELOG.md
├─jest.config.js
├─package.json
├─README.md
├─postcss.config.js
├─rollup.config.js
├─dist/
├─example/
├─node_modules/
├─src/
├─__mocks__/
└─__tests__/

Минимальные сценарии npm следующие:

// package.json

"scripts": {
  "build": "rollup --config"
},

Более базовая конфигурация свертки выглядит следующим образом:

// rollup.config.js

import path from 'path';
import json from 'rollup-plugin-json';
import { uglify } from 'rollup-plugin-uglify';
import alias from 'rollup-plugin-alias';
import vue from 'rollup-plugin-vue';
import babel from 'rollup-plugin-babel';
import commonjs from 'rollup-plugin-commonjs';
import resolve from 'rollup-plugin-node-resolve';
import nodeGlobals from 'rollup-plugin-node-globals';
import bundleSize from 'rollup-plugin-filesize';
import { eslint } from 'rollup-plugin-eslint';
import pkg from './package.json';

const pathResolve = p => path.resolve(__dirname, p);

const extensions = ['.js', '.vue'];

module.exports = {
  input: 'src/index.js',
  output: {
    file: 'dist/bundle.min.js',
    format: 'umd',
    name: 'MyComponents',
    globals: {
      vue: 'Vue',
      echarts: 'echarts',
      lodash: 'lodash'
    },
    sourcemap: true
  },
  external: Object.keys(pkg.dependencies),
  plugins: [
    resolve({
      extensions,
      browser: true
    }),
    eslint({
      extensions,
      exclude: ['**/*.json'],
      cache: true,
      throwOnError: true
    }),
    bundleSize(),
    commonjs(),
    nodeGlobals(),
    vue({
      template: {
        isProduction: !process.env.ROLLUP_WATCH,
        compilerOptions: { preserveWhitespace: false }
      },
      css: true
    }),
    babel({
      exclude: 'node_modules/**'
    }),
    alias({
      '@': pathResolve('src')
    }),
    json(),
    uglify()
  ]
};

Краткое описание этой конфигурации выглядит следующим образом:

  • Порядок плагинов в приведенном выше примере важен
  • Плагин node-globals будет вводить переменные, такие как процесс, в упакованный файл.
  • Плагин eslint проверит синтаксис перед упаковкой и может повторно использовать файл конфигурации .eslintrc.js в обычном проекте.
  • Плагин bundleSize используется для отображения размера целевого файла после упаковки.
  • Поле css в плагине vue, указывающее, следует ли упаковывать встроенные стили в целевой js.
  • Продолжайте использовать babel вместо более легкого buble, который часто сочетается с rollup для компиляции кода ES6, а также для повторного использования с шуткой.
  • Компонент json решает ситуацию, когда файл json может быть напрямую импортирован в исходный код.
  • Внешняя конфигурация означает: зависимости, содержащиеся в зависимостях в package.json, не упаковываются в компоненты, а должны быть установлены в конкретных проектах.

Связанное преобразование синтаксиса и настройка проверки синтаксиса:

// .babelrc

{
  "presets": [["env", { "modules": false }]],
  "env": {
    "test": {
      "presets": [["env", { "targets": { "node": "current" } }]]
    }
  }
}
// .eslintignore

__tests__/*
*.css
// .eslintrc.js

module.exports = {
  extends: [
    "airbnb-base",
    'plugin:vue/essential'
  ],
  rules: {
    'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
    'no-debugger': 'error',
    'space-before-function-paren': 'off',
    'no-underscore-dangle': 'off',
    'no-param-reassign': 'off',
    'func-names': 'off',
    'no-bitwise': 'off',
    'prefer-rest-params': 'off',
    'no-trailing-spaces': 'off',
    'comma-dangle': 'off',
    'quote-props': 'off',
    'consistent-return': 'off',
    'no-plusplus': 'off',
    'prefer-spread': 'warn',
    semi: 'warn',
    indent: 'warn',
    'no-tabs': 'warn',
    'no-unused-vars': 'warn',
    quotes: 'warn',
    'no-void': 'off',
    'no-nested-ternary': 'off',
    'import/no-unresolved': 'off',
    'no-return-assign': 'warn',
    'linebreak-style': 'off',
    'prefer-destructuring': 'off',
    'no-restricted-syntax': 'warn'
  },
  parserOptions: {
    parser: 'babel-eslint'
  }
}

Настройка среды модульного тестирования

Точки обслуживания объединены в библиотеку, следует отметить высокую концентрацию соответствующих рисков.

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

Здесь мы возьмем jest в качестве примера, чтобы перечислить его основную конфигурацию:

// jest.config.js

module.exports = {
  modulePaths: [
    '<rootDir>/src/'
  ],
  moduleFileExtensions: [
    'js',
    'json',
    'vue'
  ],
  transform: {
    '^.+\\.vue$': 'vue-jest',
    '^.+\\.jsx?$': 'babel-jest'
  },
  transformIgnorePatterns: [
    '/node_modules/'
  ],
  moduleNameMapper: {
    '^@/(.*)$': '<rootDir>/src/$1',
    '\\.(css|less|scss)$': '<rootDir>/__mocks__/emptyMock.js'
  },
  snapshotSerializers: [
    'jest-serializer-vue'
  ],
  collectCoverage: true,
  collectCoverageFrom: [
    '<rootDir>/src/**/*.{js,vue}',
    '!**/node_modules/**'
  ],
  coveragePathIgnorePatterns: [
    '<rootDir>/__tests__/'
  ],
  coverageReporters: [
    'text'
  ]
};

вemptyMock.jsиспользуется для игнорирования ссылок на стили в вариантах использования:

// __mocks__/emptyMock.js

module.exports = {};

Соответствующие сценарии npm:

"scripts": {
  // ...
  "test": "jest"
},
"pre-commit": [
  "test"
],

Здесь пакет pre-commit используется для реализации функции ловушки модульного тестирования перед фиксацией.

Для получения дополнительной информации о модульном тестировании Vue см.эта статья.

Предварительный просмотр фактического эффекта компонента

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

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

"scripts": {
  // ...
  "dev:common": "rollup --watch --config rollup.config.dev.js --environment PROJ_ENV:common",
  "dev:A": "rollup --watch --config rollup.config.dev.js --environment PROJ_ENV:A",
  "dev:B": "rollup --watch --config rollup.config.dev.js --environment PROJ_ENV:B",
},

Соответствующим образом измените исходную конфигурацию объединения, добавьте отдельный файл rollup.config.dev.js и запустите службу в соответствии с параметрами среды:

import serve from 'rollup-plugin-serve';
import postcss from 'rollup-plugin-postcss';
import baseConfig, {
  pathResolve,
  browserGlobals
} from './rollup.config.base';

...

const PORT = 3001;
const PROJECT = process.env.PROJ_ENV;

export default {
  input: pathResolve(`example/${PROJECT}/main.js`),
  output: {
    file: pathResolve(`example/${PROJECT}/dist/example.bundle.${PROJECT}.js`),
    format: 'umd',
    name: 'exampleApp',
    globals: browserGlobals,
    sourcemap: false
  },
  plugins: [
    postcss(),
    ...baseConfig.plugins,
    serve({
      port: PORT,
      contentBase: [
        pathResolve(`example/${PROJECT}`)
      ]
    })
  ]
};

Здесь предполагается, что компоненты ссылаются на App.vue просто и грубо.Пока что, независимо от маршрутизации и других ситуаций, структура соответствующего каталога примера может быть следующей:

+---A
|   |   App.vue
|   |   index.html
|   |   main.js
|   |
|   \---dist
|           example.bundle.A.js
|
+---B
|   |   App.vue
|   |   index.html
|   |   foo.css
|   |   main.js
|   |
|   \---dist
|           example.bundle.B.js
|
\---common
    |   App.vue
    |   index.html
    |   main.js
    |
    +---dist
    |       example.bundle.common.js
    |
    \---fonts

Суммировать

При одновременном сопровождении нескольких однородных интерфейсных проектов неизбежно задействование некоторых более общих компонентов/функциональных модулей пользовательского интерфейса, которые собираются и публикуются в npm, дополняются идеальными модульными тестами и готовыми к запуску демонстрационными примерами. Отображение и необходимая документация могут значительно сократить объем работ по обслуживанию компонентов.



--End--

Поиск FemmeLife Подпишитесь на официальный аккаунт

Пожалуйста, укажите источник