介紹如何使用webpack來幫我們打包並發佈到npm官方,且整合github來做一個demo網頁,來提供說明文章和package供人使用
前言
最近因為有想要發佈一個簡單的component到npm,主要是數字方面的控制項,在之前和這次的專案都有遇到,即然做好了便想說透過npm來供人下載,而此篇則想記錄一下如何發佈到npm,並使用github來做一個靜態網頁,當做demo頁面給人可以實際操作,而當中因為需要打包所以我們需要用到webpack,就來看看整個過程是如何達成的吧。
- 使用npm建立一個專案
- 使用webpack做一個demo頁面
- 打包node和傳統網頁都能使用的元件
- 安裝eslint來提升開發品質
- 發佈npm供人使用
- 用github做一個靜態網頁,提供demo供人使用
- 結論
首先建立一個資料夾,然後使用npm init來建立一個package.json,過程會詢問一些問題,筆者把說明貼在下方,而關於git位置的部份,基本上只要在cli建立的時候,你有提供訊息,預設就會幫你填好了。
{
"name": "vue-txt-number", // npm供人下載的名稱,npm i test
"version": "1.0.0", // npm發佈的版本,每次要發佈必定得改版號
"description": "", // 說明
"main": "dist/vue-txt-number.js", //import test from 'test'時會參考的預設檔案
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/kinanson/vue-txt-number.git"
},
"keywords": [
"vue",
"vue number",
"vue limit decimal length",
"javascript"
],
"author": "kinanson",
"license": "ISC",
"bugs": {
"url": "https://github.com/kinanson/vue-txt-number/issues"
},
"homepage": "https://github.com/kinanson/vue-txt-number#readme",
}
因為我希望打開原始碼的時候,可以有一個測試頁面,供我開發使用,所以包括babel等等我都得安裝,有時候我想改別人原始碼的時候,卻發現對方根本沒有提供開發環境,就會讓我覺得很困擾,所以適時的提供現成的開發頁面,或許會幫助更多開發者來對你的package pull request哦,接下來就說明一下如何開始吧,先安裝必要的package
npm i babel-core babel-loader babel-plugin-transform-runtime babel-preset-env babel-preset-stage-2 cross-env css-loader node-sass npm-run-all sass-loader style-loader vue-loader vue-style-loader vue-template-compiler webpack webpack-dev-server --D
有些package視需要安裝,比如說sass筆者是全部都安裝比較省事了,npm-run-all則是為了讓windows平台可以同時執行兩個npm用的,接著新增專案必要的檔案,首先在根目錄新增.babelrc
{
"presets": [
["env", { "modules": false }],
"stage-2"
],
"plugins": ["transform-runtime"]
}
接著在根目錄新增一支index.html,主要是當我們本地開發的時候能直接跑起來測試
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app"></div>
<script src="dist/app.js"></script>
</body>
</html>
接著來做一個最基本的webpack配置吧,如果你對webpack不熟或很陌生的話,可以參考筆者以前寫的文章(https://dotblogs.com.tw/kinanson/2017/06/11/124206),webpack3跟webpack2基本上都是共用的。
const path = require('path'),
webpack = require('webpack')
let webpackConfig = {
entry: {
app: './src/index.js'
},
output: {
filename: '[name].js',
path: path.resolve(__dirname + '/dist')
},
resolve: {
extensions: ['.vue', '.js']
},
devtool: '#cheap-module-eval-source-map',
module: {
rules: [
{
test: /\.js$/,
loader: 'babel-loader',
include: [path.join(__dirname, 'src'), path.join(__dirname, 'demo')],
exclude: /node_modules/
},
{
test: /\.css$/,
use: ["style-loader", "css-loader"]
},
{
test: /\.scss$/,
use: ["style-loader", "css-loader", "sass-loader"]
},
{
test: /\.vue$/,
loader: 'vue-loader'
}
]
}
}
module.exports = webpackConfig
接著改一下pakcage.json的scripts部份,因為我新增可以監控並同時跑起一個網站,所以我想要用一個命令同時執行兩個動作,所以我用start同時去執行watch和dev
"watch": "cross-env NODE_ENV=dev webpack --watch ",
"dev": "cross-env NODE_ENV=dev webpack-dev-server",
"start": "npm-run-all --parallel dev watch"
然後就可以直接執行npm start,來開始偵錯了,那src資料夾裡面的部份呢?首先新增src/index.js
import Vue from 'vue'
import Demo from './demo.vue'
new Vue({
el: '#app',
render: h => h(Demo),
template: '<Demo/>',
components: {
Demo
}
})
這支主要是在開發時候用的,接著看一下Demo.vue的部份,就是直接去使用component來做測試
<template>
<div>
<vue-txt-number v-model="number"></vue-txt-number>
</div>
</template>
<script>
import VueTxtNumber from './components/vue-txt-number.vue'
export default {
components: {
VueTxtNumber
},
data () {
return {
number: 3
}
}
}
</script>
<style>
</style>
最後再來看一下src/build.js的部份,主要就是當我們要打包發佈到npm時候會產生的js
import VueTxtNumber from './components/vue-txt-number'
const install = (Vue, opts = {}) => {
Vue.component(VueTxtNumber.name, VueTxtNumber)
}
if (typeof window !== 'undefined' && window.Vue) {
install(window.Vue)
}
export default { VueTxtNumber, install }
開發vue的人都知道彈性很大,可以掛戴一支vue.js就開始用vue來binding,或者另一種就是用cli來產生環境生態開發,偏偏很多開發元件的人,並未兩種都兼顧到,這邊先來討論一下如何打包node的元件,在npm的main我們已經有指定了一支js檔,那支就是給npm預設引用的,不過為了後續可以同時打包傳統方式也能用的元件,先來安裝一下webpack merge
npm i webpack-merge --D
接著因為我們想要在一次打包的時候,同時產生node和普通網頁都能使用的版本,所以我把webpack改成如下
const path = require('path'),
webpack = require('webpack'),
rimraf = require('rimraf'),
merge = require('webpack-merge')
let webpackConfig = {
entry: {
app: './src/index.js'
},
output: {
filename: '[name].js',
path: path.resolve(__dirname + '/dist')
},
resolve: {
extensions: ['.vue', '.js']
},
devtool: '#cheap-module-eval-source-map',
module: {
rules: [
{
test: /\.js$/,
loader: 'babel-loader',
include: [path.join(__dirname, 'src'), path.join(__dirname, 'demo')],
exclude: /node_modules/
},
{
test: /\.css$/,
use: ["style-loader", "css-loader"]
},
{
test: /\.scss$/,
use: ["style-loader", "css-loader", "sass-loader"]
},
{
test: /\.vue$/,
loader: 'vue-loader'
}
]
}
}
rimraf(path.join(__dirname, 'dist'), () => console.log('success remove'))
switch (process.env.NODE_ENV) {
case 'dev':
module.exports = webpackConfig
break
case 'prod':
webpackConfig.devtool = "#source-map"
webpackConfig.externals = { //這邊指定打包時忽略vue的package,調用者必定都會安裝vue,所以我們不需要增加vue的體積
vue: 'vue'
}
module.exports = [
merge(webpackConfig, {
entry: './src/components/vue-txt-number.vue', // 直接輸入vue檔,供node使用
output: {
filename: 'vue-txt-number.js',
libraryTarget: 'umd',
library: 'vue-txt-number', // import的名稱
umdNamedDefine: true //會對umd購建過程做命名
}
}),
merge(webpackConfig, {
entry: path.resolve('./src/build.js'),
output: {
filename: 'vue-txt-number.min.js',
libraryTarget: 'window', // 使用window變數
library: 'VueTxtNumber', // 註冊在window全局變數,所以從window會取得VueTxtNumber,在傳統網頁直接就能使用
}
})
]
break
}
接著改一下package.json,新增一個build的命令
"build": "cross-env NODE_ENV=prod webpack -p"
打包完成基本上就能看到dist有四支檔案了
vue-txt-number.min.js直接掛在src就能使用此元件囉,而vue-txt-number.js則是給node module使用的。
在開發的過程,還是希望會有檢查語法的工具,來幫助統一程式風格,所以接著就來安裝eslint吧,首先執行如下指令,安裝必要工具
npm i eslint eslint-config-standard eslint-plugin-import eslint-plugin-node eslint-plugin-promise eslint-plugin-standard eslint-plugin-vue babel-eslint --D
接著在根目錄新增.babelrc然後加入以下的內容
{
"presets": [
["env", { "modules": false }],
"stage-2"
],
"plugins": ["transform-runtime"]
}
然後是eslint的配置部份,新增.eslintrc.js
module.exports = {
root: true,
parserOptions: {
parser: 'babel-eslint'
},
env: {
browser: true,
},
extends: [
'plugin:vue/essential',
'standard'
],
plugins: [
'vue'
],
rules: {
'arrow-parens': 0,
'no-new': 0,
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off'
}
}
這樣就可以完成了用eslint來檢查我們的程式碼
這邊只講npm,就不談github了,基本上能走到這步我相信對github的基本操作應該都不會是很大的問題了,如果我們想要發佈npm的話,第一件事情就是到官方申請一下帳號(https://www.npmjs.com/signup),
註冊成功之後,進到首頁可以看到自己的npm package,像筆者目前只有一個非常不完善的元件
如果你想要打包的話,請先至專案的底下,使用cli輸入如下指令
npm adduser
接著會要你輸入帳號和密碼
完成後只要輸入如下指令就能發佈了
npm publish
特別得注意一下,如果你想要再次發佈的話,一定得要改掉package.json的version才能發佈,如果你要把發佈的專案移除掉的話,可以使用如下指令
npm unpublish
但官方非常不建議你移除掉,所以會產生如下錯誤訊息,提示你要使用--force的方式
需注意一下如果你移除掉的話,下次想要發佈就要用不同名稱或者不同版號囉,所以基本上如果有任何要測試就反覆改版號就對了,而不要用移除的方式來處理。
這邊則是選擇性的,但是最好能提供,比方我在看別人提供的第三方元件的時候,通常都會先考慮可以直接使用看看,甚至可以測試的demo,如果沒有demo的話,如果有很多其他選擇的話,我可能就會想要去選擇其他的package,而在github可以做一個自己的靜態網頁,當然也可以是一個spa的網站,那首先了解一下我們如何做一個自己的github網站吧,首先建立一個repository為自己帳號並符合此規則的名稱
kinanson.github.io
建立完成之後,以筆者的例子,是直接使用vue官方的cli來實做一個spa的網站,當我打包的時候,把此打包的目錄push到repository,需要注意這邊不能使用html5的模式,否則會404哦,可以直接看筆者的github檔案(https://github.com/kinanson/kinanson.github.io)
當我們把靜態網站放上去之後,直接訪問(帳號.github.io),就可以看到你在github上面的靜態網頁了,當然如果你有很多的package或者作品想給人看,都可以使用這個資源來提供哦,而網址則是對應到我們的spa route設定,當然如果你是一支一支的html也是可行的,就看自己如何利用了。
相信大家常常在使用別人提供的npm,有時候當我們覺得某種需求一直在出現,然後npm又沒有適合自己的元件,適時的出一份力提供給別人用,也是對開放原始碼出一份心力,如果更多元件可以使用,就會吸引更多人來用vue,有時候功能太強大的元件自己並用不到,並且使用起來挺複雜的,或許你設計的簡單元件剛好更符合某些使用者使用哦,如果想了解整個原始碼的話,可以直接去筆者的github察看。
https://github.com/kinanson/vue-txt-number