写在开头
时隔大半个月,最近终于又有些时间来写文章啦( ̄▽ ̄),写文章我一直认为是一种巩固知识的好方式,不仅加深、巩固自己学到的东西,而且会有一个比较好的整理归纳,也能方便自己随时的查阅。
而这次分享的文章主题是 element-ui
源码系列,element-ui
包括新版的 element-plus
我一直认为是两个非常棒的 UI
框架(当然其他框架也很棒啦,手动狗头保命-.-),它们是值得我们去细细品读的,你会学到很多东西,真的,信我,不吃亏。
准备
那我们废话不多说,赶紧来开始!
创建入口文件
首先,在你的电脑里寻找一个风水宝地,创建一个文件夹,通过 npm init -y
,初始化 package.json
文件;创建 src
文件夹,在它下面创建 src/index.js
入口文件,它是我们项目的总入口文件。
创建第一个组件
其次,我们来创建项目的第一个组件,先在 src
文件夹 同级 下创建 packages
文件夹,它后续会存放我们项目中的每一个组件源码;再创建第一个组件 button
的结构目录,具体如下:
后续每个组件都会在 package
文件夹下有对应名称的文件夹,它主要由一个 index.js
主文件,和 src
文件夹组成,这和 element-ui 源码结构是一样的,都是基操,就不多说了,看着建就完事。
编写入口文件与组件内容
入口文件(src/index.js
)的工作就是引入注册所有组件,并对外提供 install()
方法,供给 Vue.use()
方法使用。
// src/index.js
import Button from '../packages/Button/index.js';
const components = [Button];
const install = (Vue) => {
components.forEach(component => {
Vue.component(component.name, component); // 每个组件需提供 name 属性
})
}
export default {
install,
Button
}
button.vue
组件我们先简单随便写点东西。
// button.vue
<template>
<div>第一个组件-button组件</div>
</template>
<script>
export default {
name: 'ElButton'
};
</script>
button/index.js
组件名称我们先按 element-ui
本身的名称来,当然,你也能随便改,这不是重点。
// button/index.js
import ElButton from './src/button.vue'; // 后缀不可省略
/* istanbul ignore next */
ElButton.install = function(Vue) { // 提供给按需加载能力
Vue.component(ElButton.name, ElButton);
};
export default ElButton;
在编写 button/index.js
文件的时候,有两个需要注意的地方:一就是文件后缀的问题,因为我们项目是从零开始搭建的,没有任何其他辅助工具,所以在引入一个文件的时候,必须提供一个完整的路径。很多时候,我们已经习惯了引入文件时,省略 .js
、 .vue
和 .ts
等后缀,但这不是一个与生俱来的“能力”,那是因为我们有各种 cli
工具的集成辅助,当然,后面我们集成 webpack
后也能配置该能力;第二个需要注意的地方是在组件身上挂载 install()
方法,它的作用提供组件的 按需加载 能力,后续文章会写到,可以先不管。
打包
通过上面步骤,项目的准备工作就做完了,下面需要对项目进行打包操作,我们和 ElementUI
一样采用 webpack
来打包。
引入webpack
我们会用到两个 webpack
相关的包,为了保证不会出现不必要的麻烦,你可以先和我保持一样的版本:npm install webpack@4.14.0 webpack-cli@3.0.8 -D
。
之后在项目根目录下,新建 build
文件夹,它存放项目打包的一切相关配置文件,再创建 build/webpack.common.js
配置文件。
编写 webpack
的基本配置:
// build/webpack.common.js
const path = require('path');
module.exports = {
mode: 'production',
entry: './src/index.js',
output: {
path: path.resolve(process.cwd(), './lib'),
filename: 'element-ui.common.js',
libraryTarget: 'commonjs2', // 将库的返回值分配给module.exports
}
};
处理 .vue文件
因为我们编写的组件用的是 .vue
后缀的文件, webpack
可不认识这类型的文件,webpack
只识别 .js
与 .json
文件,其他所有类型的文件,都需要找到相关的 loader
处理后才能交给 webpack
。
(loader
是 webpack
的核心内容,这里就不多讲了,不懂的可以先找些文章瞅瞅)
处理 .vue
文件我们主要会用到两个包: npm install vue-loader@15.7.0 vue-template-compiler@2.6.14 -D
。
编写配置文件:
// build/webpack.common.js
const path = require('path');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
module.exports = {
mode: 'production',
entry: './src/index.js',
output: {
path: path.resolve(process.cwd(), './lib'),
filename: 'element-ui.common.js',
libraryTarget: 'commonjs2', // 将库的返回值分配给module.exports
},
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
compilerOptions: {
preserveWhitespace: false // 打包后清除多余的空格
}
}
},
]
},
plugins: [
new VueLoaderPlugin()
]
};
配置命令行打包
写好配置文件后,我们再配置打包命令,方便后续的打包工作。
{
"name": "juejin-element-ui",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "webpack --config build/webpack.common.js"
},
"author": "",
"license": "ISC",
"devDependencies": {
"vue-template-compiler": "^2.6.14",
"vue-loader": "^15.7.0",
"webpack": "^4.14.0",
"webpack-cli": "^3.0.8"
},
"dependencies": {}
}
执行打包命令
配置完打包命令后,我们执行它(npm run build
),在项目的根目录下的 lib
文件夹应该可以生成一个 element-ui.common.js
文件。
如果执行打包有报错,不要慌,仔细报错信息,webpack
打包错误提示还是很友好的,或者你可以截图给我留言。
测试
做到这里到这里,项目前期的工作就做完了,下面我们步入测试阶段,写了那么多,是骡子是马要拉到页面上遛遛。
下面会介绍两种测试项目的方式:
方式一:项目打包成本地npm包
- 修改
package.json
文件的main
配置项,改成打包后生成的文件。
{
"name": "juejin-element-ui",
"version": "1.0.0",
"description": "",
"main": "lib/element-ui.common.js",
"scripts": {
"build": "webpack --config build/webpack.common.js"
},
"author": "",
"license": "ISC",
"devDependencies": {
"vue-template-compiler": "^2.6.14",
"vue-loader": "^15.7.0",
"webpack": "^4.14.0",
"webpack-cli": "^3.0.8"
},
"dependencies": {}
}
- 执行
npm pack
命令,生成.tgz
包。
- 下载本地的
npm
包到实际项目中使用。
我们先随便初始化一个Vue
项目。
vue create juejin-element-ui-test(项目名,可以随意取)
然后我们在新项目中下载我们刚刚生成的本地 npm
包。
npm install F:\juejin-element-ui\juejin-element-ui-1.0.0.tgz(本地放置tgz包的全路径)
下完后,你的 Vue
项目的 package.json
文件会多一个包,之后就能和正常下载的 npm
包一样使用了。
在项目的 main.js
文件中全局导入。
import juejinElementUI from 'juejin-element-ui';
Vue.use(juejinElementUI);
在页面中具体使用。
<template>
<div id="app">
<el-button></el-button>
</div>
</template>
<script>
export default {
name: 'App',
}
</script>
能看到组件被正常识别,就大功告成了。这过程还是比较容易出错,多注意是否有重新打包、重新下载、重新启动项目等。٩(๑❛ᴗ❛๑)۶
简单总结:
1.记得把原项目打包
npm run build
。
2.修改package.json
文件的main
配置项,定位到打包后生成的入口文件。
3.执行npm pack
打包生成tgz
包。
4.下载npm install 本地放置tgz包的全路径
。
方式二:html文件快速测试.vue文件
- 创建一个
.html
文件。
我们在项目中创建examples
文件夹,在它下面创建一个.html
文件。
- 编写
html
文件内容。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Vue组件库测试</title>
<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/http-vue-loader"></script>
</head>
<body>
<div id="app">
<el-button></el-button>
</div>
<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {},
components: {
'ElButton': httpVueLoader('../packages/button/src/button.vue')
}
})
</script>
</body>
</html>
主要是借用 http-vue-loader 包来处理 .vue
文件,对它不熟悉的小伙伴可以自行了解一下。
- 把
.vue
文件export default
改成module.exports = {}
形式。
<template>
<div>第一个组件-button组件</div>
</template>
<script>
// export default {
module.exports = {
name: 'ElButton'
};
</script>
<style scoped>
</style>
- 运行
.html
文件,必须以在服务器形式运行。
我们需要启动一个服务器,通过服务器的形式来访问我们创建的index.html
,http-vue-loader 提供的例子借助express
来启动,这里我们简单点,直接用webpack-dev-server
包:npm install webpack-dev-server@3.1.11 -D
。
再来配置一条启动服务器的命令:
{
"name": "juejin-element-ui",
"version": "1.0.0",
"description": "",
"main": "lib/element-ui.common.js",
"scripts": {
"dev": "webpack-dev-server --config build/webpack.common.js",
"build": "webpack --config build/webpack.common.js"
},
"author": "",
"license": "ISC",
"devDependencies": {
"vue-loader": "^15.7.0",
"vue-template-compiler": "^2.6.14",
"webpack": "^4.14.0",
"webpack-cli": "^3.0.8",
"webpack-dev-server": "^3.1.11"
},
"dependencies": {}
}
执行 npm run dev
,访问 http://localhost:8081/examples/
就能看到效果啦。
有个坑: 在我们做完上述步骤后,我们要运行
.html
文件,这里可不要直接就双击去打开它,要不你只能收到一系列的报错。主要是 http-vue-loader 的使用需要一些环境要求:
至此,本篇文章就写完啦,撒花撒花。