С тех пор, как я присоединился к компании в марте этого года, я работаю над фоновой операционной системой, и у меня много повторяющихся задач, одной из которых является библиотека компонентов. Хотя на данном этапе существует множество отличных библиотек компонентов с открытым исходным кодом, чтобы удовлетворить странные потребности продукта, некоторые компоненты должны быть реализованы вручную. Успокойтесь и накопите что-то свое.
Обзор: Во-первых, на основе скаффолдинга Vue-cli изменен базовый инструмент построения библиотеки компонентов, который имеет следующие функции:
- webpack3.0 обновить webpack4.0 => лучше завершить разработку и упаковку компонентов;
- Поддержка sass => ускорение разработки стилей компонентов;
- Поддержка импорта уценки и настройки стиля уценки, а также подсветка кода;
- Маршрутизация настраивается автоматически.
Добавлено 25 декабря 2018 г.
- Пакет выделения слишком велик, а языковой пакет уменьшен;
- проверка дублирования кода jscpd.
предыдущийv-highlightинструкция
// 这样加载了highlight所有的代码语言包,有300kb+
import hljs from 'highlight.js'
import 'highlight.js/styles/vs2015.css'
hljs.configure({ useBR: true })
Vue.directive('highlight',function (el) {
let blocks = el.querySelectorAll('code')
blocks.forEach(block => {
hljs.highlightBlock(block)
})
})
превратиться в
import hljs from 'highlight.js/lib/highlight';
import 'highlight.js/styles/github.css';
// 只加载Html、JavaScript
import javascript from 'highlight.js/lib/languages/javascript';
import xml from 'highlight.js/lib/languages/xml';
hljs.registerLanguage('javascript', javascript);
hljs.registerLanguage('xml', xml);
Vue.directive('highlight', function (el) {
let blocks = el.querySelectorAll('code')
Array.prototype.forEach.call(blocks, block => {
hljs.highlightBlock(block)
})
})
установить jscpd,npm i --save-dev jscpd, изменить packjson.json
{
....
"scripts": {
"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
"start": "npm run dev",
// 添加
"check": "jscpd src",
"build": "node build/build.js"
},
...
}
результат операции
1. Примеры
Кодовый адрес:UI-Library code
2. Процесс установки
Среда: win-64 бит, node-v8.12.0
-
Установить
npm install --global vue-cliУстановите vue-cli, затем создайте проект ui-library.
vue init webpack ui-libraryВ package.json созданного проекта версия webpack 3.6.0
"webpack": "^3.6.0", "webpack-bundle-analyzer": "^2.9.0", "webpack-dev-server": "^2.9.1", "webpack-merge": "^4.1.0"Чтобы обновить webpack4.1.2, сначала удалите текущий webpack и связанные с ним зависимости.
npm uninstall -D webpack webpack-bundle-analyzer webpack-dev-server webpack-merge npm uninstall -D copy-webpack-plugin css-loader eslint-loader file-loader html-webpack-plugin url-loader friendly-errors-webpack-plugin optimize-css-assets-webpack-plugin uglifyjs-webpack-plugin vue-loaderУстановите webpack4, так как webpack4 зависит от webpack-cli, его тоже нужно установить
npm install -D webpack webpack-cli webpack-bundle-analyzer webpack-dev-server webpack-merge npm install -D copy-webpack-plugin css-loader eslint-loader file-loader html-webpack-plugin url-loader friendly-errors-webpack-plugin optimize-css-assets-webpack-plugin uglifyjs-webpack-plugin vue-loaderручная замена
extract-text-webpack-pluginплагинnpm uninstall -D extract-text-webpack-pluginзаменитьnpm install -D mini-css-extract-pluginУстановите зависимости, связанные с sass
npm install -D node-sass sass-loader --save-dev -
настроить
-
Сначала настройте режим веб-пакета и добавьте его в webpack.dev.conf.js и webpack.prod.conf.js соответственно.
const devWebpackConfig = merge(baseWebpackConfig, { mode: 'production', ... })const webpackConfig = merge(baseWebpackConfig, { mode: 'development', ... }) -
Настройте файл webpack.base.conf.js
// 引入VueLoaderPlugin const { VueLoaderPlugin } = require('vue-loader') // 添加至 const devWebpackConfig = merge(baseWebpackConfig, { ... plugins: [ new VueLoaderPlugin(), ... ] }) -
Настройте файл webpack.prod.conf.js
нужно удалить
const ExtractTextPlugin = require('extract-text-webpack-plugin')const UglifyJsPlugin = require('uglifyjs-webpack-plugin')Затем настройте элемент конфигурации
const ExtractTextPlugin = require('extract-text-webpack-plugin') const { VueLoaderPlugin } = require('vue-loader') const webpackConfig = merge(baseWebpackConfig, { optimization: { splitChunks: { cacheGroups: { vendors: { test: /[\\/]node_modules[\\/]/, chunks: 'initial', name: 'vendors', }, 'async-vendors': { test: /[\\/]node_modules[\\/]/, minChunks: 2, chunks: 'async', name: 'async-vendors' } } }, runtimeChunk: { name: 'runtime' } }, plugins: [ // 添加VueLoaderPlugin new VueLoaderPlugin(), ... // 引入MiniCssExtractPlugin new MiniCssExtractPlugin({ filename: utils.assetsPath('css/[name].[contenthash:7].css') }), // Compress extracted CSS. We are using this plugin so that possible // duplicated CSS from different components can be deduped. new OptimizeCSSPlugin({ cssProcessorOptions: config.build.productionSourceMap ? { safe: true, map: { inline: false } } : { safe: true } }), // see https://github.com/ampedandwired/html-webpack-plugin new HtmlWebpackPlugin({ filename: config.build.index, template: 'index.html', inject: true, minify: { removeComments: true, collapseWhitespace: true, removeAttributeQuotes: true // more options: // https://github.com/kangax/html-minifier#options-quick-reference }, // necessary to consistently work with multiple chunks via CommonsChunkPlugin chunksSortMode: 'dependency' }), // keep module.id stable when vendor modules does not change new webpack.HashedModuleIdsPlugin(), // copy custom static assets new CopyWebpackPlugin([ { from: path.resolve(__dirname, '../static'), to: config.build.assetsSubDirectory, ignore: ['.*'] } ]) ] -
Изменить utils.js
exports.cssLoaders = function(options) { options = options || {} // generate loader string to be used with extract text plugin function generateLoaders(loader, loaderOptions) { let loaders = [] if (loader) { loaders = [{ loader: loader + '-loader', options: Object.assign({}, loaderOptions, { sourceMap: options.sourceMap }) }] } if (options.extract) { let extractLoader = { loader: MiniCssExtractPlugin.loader, options: {} } return [extractLoader, 'css-loader'].concat(['postcss-loader'], loaders) } else { return ['vue-style-loader', 'css-loader'].concat(['postcss-loader'], loaders) } } return { css: generateLoaders(), postcss: generateLoaders(), less: generateLoaders('less'), sass: generateLoaders('sass', { indentedSyntax: true }), scss: generateLoaders('sass'), stylus: generateLoaders('stylus'), styl: generateLoaders('stylus') } } -
представлять
sass-resources-loaderОбработка общедоступных файлов cssnpm install -D sass-resources-loader --save-devизменить вышеуказанное
returnценность{ ... scss: generateLoaders('sass').concat({ loader: 'sass-resources-loader', options: { resources: path.resolve(__dirname, '../src/assets/styles/common.scss') } }) ... }
-
3. Поддержка уценки импорта и настройки стиля уценки
из-заvue-markdown-loaderСуществуют проблемы совместимости с vue-loader версии 15, поэтому используйтеtext-loaderИмпортируйте документ Markdown и создайте String, а затем скомпилируйте его в документ Markdown.
первыйnpm install -D text-loaderУстановите текстовый загрузчик для импорта файлов *.md, а затем измените файл webpack.base.conf.js, чтобы добавить текстовый загрузчик.
rules: [
...(config.dev.useEslint ? [createLintingRule()] : []),
{
test: /.md$/,
loader: 'text-loader'
},
...
]
Во введенииmarkedСкомпилировать импортированную строку
<template>
<div class="markdown-body" v-html="compiledMarkdown" v-highlight></div>
</template>
import markdown from '../../README.md'
import marked from 'marked'
export default {
computed: {
markdowonText () {
// 编译markdown
return marked(markdown)
}
}
}
Я думаю, что стиль уценки немного уродлив, вы можете импортировать егоgithub-markdown-css
npm install -D github-markdown-css
Измените стиль. Если в уценке есть какой-то код, можно передатьhighlightЧтобы выделить
npm install -D highlight
import hljs from 'highlight.js'
// 调整高亮code的样式
import 'highlight.js/styles/vs2015.css'
hljs.configure({ useBR: true })
// 注册一个directive用来添加code高亮
Vue.directive('highlight',function (el) {
let blocks = el.querySelectorAll('code')
blocks.forEach(block => {
hljs.highlightBlock(block)
})
})
4. Автоматически настраивать маршрутизацию
использоватьrequire.contextПроанализируйте файлы в каталоге и сгенерируйте конфигурацию маршрутизатора.
const context = require.context('@/components/', true, /demo\.vue$/)
const componentRouters = context.keys().map(url => {
const start = url.indexOf('/')
const end = url.lastIndexOf('/')
const name = url.substring(start + 1, end)
const path = `/${name}`
return {
name,
path,
component: require(`@/components${path}/demo`).default
}
})
export default new Router({
routes: [
{
path: '/',
name: 'mainPage',
component: mainPage
},
...componentRouters
]
}
)
Прошлые статьи:
- Внедрение библиотеки компонентов Vue с нуля (ноль) — базовая структура и инструменты сборки
- Внедрение библиотеки компонентов Vue с нуля (1) — реализация Toast
- Внедрение библиотеки компонентов Vue с нуля (2) — Реализация слайдера
- Внедрение библиотеки компонентов Vue с нуля (3) — реализация вкладок
- Внедрение библиотеки компонентов Vue с нуля (4) — реализация File-Reader
- Внедрение библиотеки компонентов Vue с нуля (5) — реализация хлебных крошек
- Внедрение библиотеки компонентов Vue с нуля (6) — реализация Hover-Tip
- Внедрение библиотеки компонентов Vue с нуля (7) — реализация Message-Box
- Внедрение библиотеки компонентов Vue с нуля (8) — реализация ввода
- Внедрение библиотеки компонентов Vue с нуля (9) — реализация InputNumber
- Внедрение библиотеки компонентов Vue с нуля (10) — выбор реализации
- Внедрение библиотеки компонентов Vue с нуля (11) — реализация средства выбора даты
- Реализация библиотеки компонентов Vue с нуля (12) — реализация таблицы
- Внедрение библиотеки компонентов Vue с нуля (13) — реализация разбиения на страницы
- Реализация библиотеки компонентов Vue с нуля (14) — реализация RadioGroup
- Внедрение библиотеки компонентов Vue с нуля (15) — реализация CheckboxGroup
Оригинальное заявление: Данная статья является оригинальной, при перепечатке просьба указывать источник.