Вы создали потрясающий компонент с Vue.js, который, как вы думаете, могут использовать другие разработчики в своих проектах. Как вы можете поделиться этим с ними?
В этой статье я покажу вам, как подготовить свой компонент, чтобы его можно было упаковать и опубликовать в NPM. Я буду использовать пример проекта и продемонстрирую следующее:
- Обеспечение зависимости не включены в пакет
- Использование Webpack для создания отдельных сборок для браузера и Node
- Создание плагина для браузера
- Важная конфигурация package.json
- Публикация на НПМ
Пример проекта: Vue Clock
Я создал этот простой компонент часов, который я собираюсь опубликовать на NPM. Возможно, это не самый крутой компонент, который вы когда-либо видели, но он достаточно хорош для демонстрации.
Вот файл компонента. Здесь нет ничего особенного, но обратите внимание, что я импортирую библиотеку моментов , чтобы отформатировать время. Важно исключить зависимости из вашего пакета, которые мы вскоре рассмотрим.
Clock.vue
HTML
xxxxxxxxxx
1
<template>
2
<div>{{ display }}</div>
3
</template>
4
<script>
5
import moment from 'moment';
6
export default {
8
data() {
9
return {
10
time: Date.now()
11
}
12
},
13
computed: {
14
display() {
15
return moment(this.time).format("HH:mm:ss");
16
}
17
},
18
created() {
19
setInterval(() => {
20
this.time = Date.now();
21
}, 1000);
22
}
23
}
24
</script>
Ключевой инструмент: Webpack
Большая часть того, что мне нужно сделать, чтобы подготовить этот компонент для NPM, делается с помощью Webpack. Вот основные настройки Webpack , которые я добавлю в этой статье. Это не должно включать много сюрпризов, если вы ранее использовали Vue и Webpack:
webpack.config.js
JavaScript
xxxxxxxxxx
1
const webpack = require('webpack');
2
const path = require('path');
3
module.exports = {
5
entry: path.resolve(__dirname + '/src/Clock.vue'),
6
output: {
7
path: path.resolve(__dirname + '/dist/'),
8
filename: 'vue-clock.js'
9
},
10
module: {
11
loaders: [
12
{
13
test: /\.js$/,
14
loader: 'babel',
15
include: __dirname,
16
exclude: /node_modules/
17
},
18
{
19
test: /\.vue$/,
20
loader: 'vue'
21
},
22
{
23
test: /\.css$/,
24
loader: 'style!less!css'
25
}
26
]
27
},
28
plugins: [
29
new webpack.optimize.UglifyJsPlugin( {
30
minimize : true,
31
sourceMap : false,
32
mangle: true,
33
compress: {
34
warnings: false
35
}
36
})
37
]
38
};
внешность
Параметр externals
конфигурации позволяет исключить зависимости из выходного пакета Webpack. Я не хочу, чтобы мой пакет включал зависимости, потому что они будут раздувать его размер и потенциально вызывать конфликты версий в среде пользователя. Пользователь должен будет установить зависимости самостоятельно.
В этом проекте я использую библиотеку моментов в качестве зависимости. Чтобы убедиться, что он не входит в мой пакет, я определю его как внешний в моей конфигурации Webpack:
webpack.config.js
JavaScript
xxxxxxxxxx
1
module.exports = {
2
3
externals: {
4
moment: 'moment'
5
},
6
7
}
Окружающая среда строит
В Vue.js есть две разные среды, где пользователь может захотеть установить компонент. Во-первых, браузер, например
HTML
xxxxxxxxxx
1
<script type="text/javascript" src="vue-clock.js"></script>
Во-вторых, среды разработки на основе Node.js, например
JavaScript
xxxxxxxxxx
1
import VueClock from 'vue-clock';
В идеале я хочу, чтобы пользователи могли использовать Vue Clock в любой среде. К сожалению, эти среды требуют, чтобы код был связан по-разному, что означает, что мне придется настроить две разные сборки.
Для этого я создам две отдельные конфигурации Webpack. Это проще, чем кажется, потому что конфигурации будут почти идентичны. Сначала я создам общий объект конфигурации, затем использую webpack-merge, чтобы включить его в обе конфигурации среды:
webpack.config.js
JavaScript
xxxxxxxxxx
1
const webpack = require('webpack');
2
const merge = require('webpack-merge');
3
const path = require('path');
4
var commonConfig = {
6
output: {
7
path: path.resolve(__dirname + '/dist/'),
8
},
9
module: {
10
loaders: [ ]
11
},
12
externals: { },
13
plugins: [ ]
14
};
15
module.exports = [
17
// Config 1: For browser environment
19
merge(commonConfig, {
20
}),
22
// Config 2: For Node-based development environments
24
merge(commonConfig, {
25
})
27
];
Общая конфигурация точно так , как это было раньше (я сокращенная большинство из них для экономии места), за исключением того, что я удалил entry
и output.filename
варианты. Я укажу их индивидуально в отдельных конфигурациях сборки.
Браузер Бандл
Браузеры не могут импортировать модули JavaScript из другого файла так же, как это делает Node. Они могут использовать загрузчик скриптов, такой как AMD, но для максимальной простоты я хочу, чтобы мой компонентный скрипт был добавлен проще как глобальная переменная.
Кроме того, я не хочу, чтобы пользователь слишком долго думал, чтобы понять, как использовать компонент. Я сделаю так, чтобы компонент мог быть легко зарегистрирован как глобальный компонент, когда пользователь включает скрипт. Система плагинов Vue поможет здесь.
Результат, к которому я стремлюсь, - это простая настройка:
index.html
HTML
xxxxxxxxxx
1
<body>
2
<div id="app">
3
<vue-clock></vue-clock>
4
</div>
5
<script type="text/javascript" src="vue-clock.js"></script>
6
<script type="text/javascript">
7
Vue.use(VueClock);
8
</script>
9
</body>
Plugin
Во-первых, я создам плагин-плагин для простой установки компонента:
plugin.js
JavaScript
xxxxxxxxxx
1
import Clock from './Clock.vue';
2
module.exports = {
4
install: function (Vue, options) {
5
Vue.component('vue-clock', Clock);
6
}
7
};
Этот плагин регистрирует компонент глобально, поэтому пользователь может вызывать компонент часов в любом месте своего приложения.
Конфигурация Webpack
Теперь я буду использовать файл плагина в качестве точки входа для сборки браузера. Я выведу файл, vue-clock.min.js
который будет наиболее очевидным для пользователя.
JavaScript
xxxxxxxxxx
1
module.exports = [
2
merge(config, {
3
entry: path.resolve(__dirname + '/src/plugin.js'),
4
output: {
5
filename: 'vue-clock.min.js',
6
}
7
}),
8
9
];
Экспорт в виде библиотеки
Webpack может предоставлять ваш сценарий различными способами, например, как модуль AMD или CommonJS, как объект, как глобальную переменную и т. Д. Вы можете указать это с помощью libraryTarget
опции.
Для комплекта браузера я буду использовать window
цель. Я также мог бы использовать UMD
для большей гибкости, но так как я уже создаю два пакета, я ограничу этот пакет для использования в браузере.
Я также укажу имя библиотеки как «VueClock». Это означает, что когда браузер включает пакет, он будет доступен как глобальный window.VueClock
.
Простой текст
xxxxxxxxxx
1
output: {
2
filename: 'vue-clock.min.js',
3
libraryTarget: 'window',
4
library: 'VueClock'
5
}
Узел Bundle
Чтобы позволить пользователям использовать компонент в среде разработки на основе узлов, я буду использовать целевой объект библиотеки UMD для комплекта узлов. UMD - это гибкий тип модуля, который позволяет использовать код в различных загрузчиках сценариев и средах.
JavaScript
xxxxxxxxxx
1
module.exports = [
2
3
merge(config, {
4
entry: path.resolve(__dirname + '/src/Clock.vue'),
5
output: {
6
filename: 'vue-clock.js',
7
libraryTarget: 'umd',
8
// These options are useful if the user wants to load the module with AMD
10
library: 'vue-clock',
11
umdNamedDefine: true
12
}
13
})
14
];
Обратите внимание, что узел Node использует однофайловый компонент в качестве точки входа и не использует плагин-плагин, так как он не нужен. Это позволяет более гибкую установку:
JavaScript
xxxxxxxxxx
1
import VueClock from 'vue-clock';
2
new Vue({
4
components: {
5
VueClock
6
}
7
});
package.json
Перед публикацией в NPM я настрою свой файл package.json . Подробное описание каждой опции доступно на npmjs.com .
package.json
JSON
xxxxxxxxxx
1
{
2
"name": "vue-clock-simple",
3
"version": "1.0.0",
4
"description": "A Vue.js component that displays a clock.",
5
"main": "dist/vue-clock.js",
6
"scripts": {
7
"build": "rimraf ./dist && webpack --config ./webpack.config.js"
8
},
9
"author": "Anthony Gore",
10
"license": "MIT",
11
"dependencies": {
12
"moment": "^2.18.1"
13
},
14
"repository": { },
15
"devDependencies": { }
16
}
Я сократил большую часть этого файла, но важно отметить следующее:
1. Основной файл сценария т.е. "main": "dist/vue-clock.js"
. Это указывает на файл комплекта узлов, гарантируя, что загрузчики модулей знают, какой файл читать, т.е.
JavaScript
xxxxxxxxxx
1
import VueClock from 'vue-clock' // this resolves to dist/vue-clock.js
2. Зависимости . Поскольку я исключил все зависимости из пакета, пользователи должны установить зависимости, чтобы использовать пакет.
Публикация в NPM
Теперь, когда мой компонент настроен правильно, он готов к публикации в NPM. Я не буду повторять здесь инструкции, так как они хорошо описаны на npmjs.com .
Вот результат: