目前最新的vuecli版本是3,而vuecli3与vuecli2都使用了相同的命令vue,所以vuecli2被覆盖了,如果要使用vuecli2的init命令创建工程,需要安装一个桥接工具:@vue/cli-init
npm install -g @vue/cli-init
# `vue init` 的运行效果将会跟 `vue-cli@2.x` 相同
vue init webpack my-project
官方说明地址:创建一个项目
- 创建一个vuecli2项目
在创建项目的过程中,选项如下:vue init webpack demo-vuecli2-ui- Vue build:选择只要运行时版本的,因为这里不需要编译模板字符串版本,读者可以根据需要自行配置,对本次按需引入打包配置无关;
- 不需要vue-router
- 不需要eslint
- 不需要unit test
- 不需要e2e test
- 不要自动执行npm install,自行处理

- 打开项目,执行
npm install安装依赖 - 安装完之后,
npm run dev启动,检查是否正常。

一切正常 - 这里组件库的名字为:
demo-vuecli2-ui,现在开始写组件,这里只写两个组件:- pl-button
- pl-input
除了这两个组件之外,还需要有一个体积比较大的组件,不然到时候测试按需引入的时候,很难观察到只引入部分组件(比如只引入button)所带来的打包体积优化效果。这里这个体积比较大的组件,使用element-ui来替代,把element-ui当做一个组件看待
- 安装element-ui
这里为什么要npm i element-ui -D-D,-D是--save-dev的缩写,-S是--save的缩写,--save会将依赖添加到package.json的dependency列表中,如果是--save-dev,会将依赖添加到devDependency列表中。将组件打包,然后发布到npm仓库之后,用户可以通过npm i demo-vuecli2-ui --save安装依赖,这时候,用户安装的时候也会去下载element-ui,这个可以通过观察node_modules/demo-vuecli2-ui目录验证,这个目录下面也会有一个node_modules文件夹,其中就是demo-vuecli2-ui的dependency列表。实际上用户是不需要再次安装下载element-ui的,所以这里是-D; - 编写组件,根目录下创建components文件夹,目录结构:
文件内容:- components - button - index.js - pl-button.vue - ele - index.js - input - index.js - pl-input.vue - index.js/*components/button/index.js*/ import Button from './pl-button' Button.install = (Vue) => Vue.component(Button.name, Button); export default Button/*components/button/pl-button.vue*/ <template> <div class="pl-button"> pl-button </div> </template> <script> export default { name: "pl-button" } </script> <style lang="scss"> .pl-button { background-color: maroon; color: white; } </style>/*components/ele/index.js*/ import ELE from 'element-ui' import 'element-ui/lib/theme-chalk/index.css' export default { install(Vue) { Vue.use(ELE) }, }/*components/input/index.js*/ import Input from './pl-input' Input.install = (Vue) => Vue.component(Input.name, Input) export default Input
这个是总的打包入口/*components/input/pl-input.vue*/ <template> <div class="pl-input"> pl-input </div> </template> <script> export default { name: "pl-input" } </script> <style lang="scss"> .pl-input { background-color: #42b983; color: white; } </style>/*components/index.js*/ import Button from './button' import Input from './input' import Ele from './ele' export default { install(Vue) { Vue.use(Button) Vue.use(Input) Vue.use(Ele) }, }
这样用户在全引入组件库`demo-vuecli2-ui`,因为element-ui的存在,打包的体积会非常大,而用户在按需引入button以及input的时候,因为没有element-ui,打包的体积会大大缩小; - 修改webpack配置文件,配置好调试组件以及打包组件的相关配置
- 修改
src/main.js,全引入组件,用来调试组件:import Vue from 'vue' import App from './App' import DVU from 'demo-vuecli2-ui' Vue.use(DVU) Vue.config.productionTip = false /* eslint-disable no-new */ new Vue({ el: '#app', render: h => h(App) }) - 修改
src/app.vue,调试组件:<template> <div id="app"> <img src="./assets/logo.png"> <pl-button/> <pl-input/> <el-button>hello world</el-button> <el-input/> </div> </template> <script> export default { name: 'App', components: {} } </script> <style> #app { font-family: 'Avenir', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style> - 修改config/index.js,设置打包的输出文件夹为lib,同时js,css等资源文件输出路径由原来的lib/static改为lib。
- 修改build.assetsRoot为:
path.resolve(__dirname, '../lib'),; - 修改build.assetsSubDirectory为:’’,就是一个空的字符串;
- 修改build.assetsRoot为:
- 修改package.json
- 删除"private":true
- 添加"main":“lib/index.js”
- 添加"files":[“lib”]
- 修改build/utils.js
- 在底部添加以下方法,用来扫描组件入口信息
const fs = require('fs') const join = path.join const resolve = (dir) => path.join(__dirname, '../', dir) exports.getComponentEntries = (path) => { let files = fs.readdirSync(resolve(path)); const componentEntries = files.reduce((ret, item) => { const itemPath = join(path, item) const isDir = fs.statSync(itemPath).isDirectory(); if (isDir) { ret[item] = resolve(join(itemPath, 'index.js')) } else { const [name] = item.split('.') ret[name] = resolve(`${itemPath}`) } return ret }, {}) console.dir(componentEntries) return componentEntries }
- 在底部添加以下方法,用来扫描组件入口信息
- 修改build/webpack.base.conf.js
- 删除module.exports.entry,里面应该只有一个app入口;
- resolve.alias添加一个:
'demo-vuecli2-ui': resolve('components/index.js'),
- 修改build/webapck.dev.conf.js
- module.exports中添加app入口,因为现在打包组件不需要打包页面了,只有调试组件的时候才需要这个入口,所以这里将这个app入口从webpack.base.conf.js中移到webpack.dev.conf.js:
entry: { app: './src/main.js' },
- module.exports中添加app入口,因为现在打包组件不需要打包页面了,只有调试组件的时候才需要这个入口,所以这里将这个app入口从webpack.base.conf.js中移到webpack.dev.conf.js:
- 修改build/webapck.prod.conf.js
- module.exports添加入口:
entry: { ...utils.getComponentEntries('components') }, - module.exports.output改为:
path: config.build.assetsRoot, filename: utils.assetsPath('[name].js'), libraryTarget: 'commonjs2', libraryExport: 'default', library: 'demo-vuecli2-ui', - ExtractTextPlugin中的filename配置为:
filename: utils.assetsPath('css/[name].css'), - 删除new HtmlWebpackPlugin(打包组件不需要页面)
- 删除所有的new webpack.optimize.CommonsChunkPlugin(打包组件的时候不需要抽离公共的部分,否则在按需引入组件的时候,还得引入一些chunk-vendor以及chunk-common等js文件)
- 删除new CopyWebpackPlugin(不需要将static目录拷贝到组件打包的目录)
- module.exports添加入口:
- 修改
- 修改完毕,启动本地调试,查看效果:
![[外链图片转存失败(img-7SXw0i3o-1566801706630)(2C1E88BA4B30409B83BE99C88680ED60)]](https://i-blog.csdnimg.cn/blog_migrate/b0d29299d5a024925d2330da94b9fd72.png)
自定义的pl-button、pl-input以及element-ui的组件都显示正常; - 打包:
npm run build,打包结果:
![[外链图片转存失败(img-VB3toVYn-1566801706631)(B5A3BE94EEDD4318AC3A79340AD47E99)]](https://i-blog.csdnimg.cn/blog_migrate/bc041125dc857775e60a1dd34c25623b.png)
- 发布到npm中,没有npm账号的同学,请自行注册账号以及在本地设备终端中登录;修改package.json文件中的版本号为
0.0.1,然后发布:
发布结果:npm publish
![[外链图片转存失败(img-Cf5Z0qPv-1566801706632)(514865F4021444F6AE4E5D48B07B8E35)]](https://i-blog.csdnimg.cn/blog_migrate/59b4da6378cf12fa9883ef1428c0d4c3.png)
看到这个+ demo-vuecli2-ui@0.0.1表示发布成功。 - 接下来使用上一篇文章创建的
test-load-on-demand工程测试按需引入是否配置成功。- 打开test-load-on-demand工程,安装
demo-vuecli2-ui:npm i vuecli2-ui@0.0.1 -S - 修改
.babelrc文件:{ "presets": ["@vue/app", ["@babel/preset-env", { "modules": false }]], "plugins": [ [ "component", { "libraryName": "demo-vuecli2-ui", "style": true, "styleLibrary": { "base": false, "name": "css" } } ] ] } - 修改src/main.js,全引入demo-vuecli2-ui:
import Vue from 'vue' import App from './App.vue' import DVU from 'demo-vuecli2-ui' import 'demo-vuecli2-ui/lib/css/index.css' Vue.use(DVU) Vue.config.productionTip = false new Vue({ render: h => h(App), }).$mount('#app') - 修改App.vue,显示所有demo-vuecli2-ui的组件:
<template> <div id="app"> <img alt="Vue logo" src="./assets/logo.png"> <pl-button/> <pl-input/> <el-button>hello world</el-button> <el-input/> </div> </template> <script> export default { name: 'app', } </script> <style lang="scss"> </style> - 启动,检查效果:
![[外链图片转存失败(img-jR8vUC7X-1566801706632)(31AFDAE85A8741608BB24E32EBF27A9D)]](https://i-blog.csdnimg.cn/blog_migrate/77e35520bda29c6dc62f51c02d315523.png)
可以看到,app.js文件大小为4.0m - 打包页面,在浏览器中打开index.html
![[外链图片转存失败(img-eXCgwGKN-1566801706632)(25EFA7EEA7734C93B70A9BC94FFFDD21)]](https://i-blog.csdnimg.cn/blog_migrate/37c7ea3f1030f58d94d624f1c5ac9433.png)
可以看到,chunk-vendor文件大概800多k; - 配置为按需引入,src/main.js:
import Vue from 'vue' import App from './App.vue' import {Button, Input} from 'demo-vuecli2-ui' Vue.use(Button) Vue.use(Input) Vue.config.productionTip = false new Vue({ render: h => h(App), }).$mount('#app') - 启动,检查效果:
![[外链图片转存失败(img-xlWWJ5hF-1566801706632)(977BBE3D12DB432FB3BFDA3DAACDBA7A)]](https://i-blog.csdnimg.cn/blog_migrate/1246275cd2c42cbdeb416c525256872c.png)
可以看到,app.js变为了1.8m - 打包,然后直接打开index.html,检查效果:
![[外链图片转存失败(img-vPFJkHpa-1566801706632)(0D9954A4B4EB4DAB8CA2A9E5E82155E2)]](https://i-blog.csdnimg.cn/blog_migrate/a6ba27a61ed0d94e20853c0f20195331.png)
可以看到,chunk-vendor变成了80k大小 - 至此,vuecli2工程组件库按需引入说明已经结束
- 打开test-load-on-demand工程,安装
4644

被折叠的 条评论
为什么被折叠?



