探索 parcel(tree-shaking) 构建 vue 插件
2021/6/29 23:50:47
本文主要是介绍探索 parcel(tree-shaking) 构建 vue 插件,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
一、打包公共代码
在 webpack4
中,可以通过 optimization.minimize
将公共代码进行打包,虽然我个人认为这个东西对SPA应用来说,效果其实有限,但有胜于无,文字再小也是肉不是,所以说,在细节的把控上,永远是无止境的。但是在webpack4中也是将CommonsChunkPlugin 改用 SplitChunksPlugin 了。感觉评论掘友的提醒。
new webpack.optimize.CommonsChunkPlugin({ name: ['vendor','runtime'], filename: '[xxxxx].js' }) 复制代码
删除沉淀代码
二、使用 Tree-Shaking
插件
本次我们要做的是编写一个 vue 的 Tag 组件,使用 parcel 结合 tree-shaking 进行打包。
本次要讲的重点是用 parcel 构建 vue,教大家如何去写一个可以供别的使用的 vue 组件,并发布到 npm 上。
Tag 组件源码分析不是这篇文章的重点,重点是构建思路。
首先说一下为啥使用 parcel 打包而没用 webpack,出发点很简单,为了用 parcel 而用 parcel,哈哈~~~!其实 parcel 有一个优点就是零配置打包,这次使用 parcel 真的是一行配置代码没写。。。 而且 parcel-bundler 是安装到全局的,所以就是说在整个项目中都没有构建工具的痕迹(webpack 4也能做到。。。),parcel 会把你使用的工具都帮你配置好,不过得需要自己安装包。这是官网 https://zh.parceljs.org/getting_started.html,不过遗憾的是里面的 API 不全。。。很多新版本更新的 api 没有在文档里说明,需要自己去 Google,比如本次要用到的 tree-shaking 配置:--experimental-scope-hoisting,在 api 里就没有,在 https://medium.com/@devongovett/parcel-v1-9-0-tree-shaking-2x-faster-watcher-and-more-87f2e1a70f79 里面有详细说明。
下面是项目目录结构:
project │ README.md │ entry.js │ package.json │ .babelrc │ .npmignore │ └─── src │ │ index.js │ │ tag.vue │ │ │ └─── fonts │ │ iconfont.ttf │ │ iconfont.woff │ └─── demo │ │ App.vue │ │ index.html │ │ main.js │ └─── es │ index.js
因为组件比较简单,所以没有使用 vue-cli 创建,直接 npm init
,然后安装需要的包
npm install vue -S
npm install vue-template-compiler babel-preset-env babel-plugin-syntax-jsx babel-plugin-transform-vue-jsx babel-helper-vue-jsx-merge-props -D
还有一些其他包,parcel 有一个 autoinstall 功能,是可以自动去 install 项目中引用但是没有下的包。
其中,vue-template-compiler
的作用是解析 .vue 文件的,babel-preset-env
解析 es6 的语法,babel-plugin-syntax-jsx
babel-plugin-transform-vue-jsx
babel-helper-vue-jsx-merge-props
这三个是解析 vue 中的 jsx 语法用的。
.babelrc
{ "presets": [ ["env", { "modules": false }] ], "plugins": ["transform-vue-jsx"] }
entry.js:打包的入口文件,暴露出 Tag 组件
import Tag from './src'; export default Tag;
src 文件夹:存放源代码
src ---> index.js
import Tag from './tag'; function install (Vue) { if (install.installed) return; install.installed = true; Vue.component(Tag.name, Tag); } const SftcTag = { install, Tag }; if (typeof window !== undefined && window.Vue) { window.Vue.use(SftcTag) } export default SftcTag
index.js 暴露出一个对象,包含有两个属性,Tag 是组件代码,install 为了使用 vue.use 注册 vue 插件。
重点:install 中有一个小技巧,就是这个方法接受了 Vue 参数来注册全局组件。没有在文件中直接使用 import Vue from 'vue'; 的原因是这种引用的 vue 其实是 node_modules 中的 vue/dist/vue.runtime.esm.js,而我们需要利用 tree-shaking 将 vue 抽离出去的时候使用的 vue 应该是 node_modules/vue/dist/vue.common.js,所以需要使用不同 Vue 进行注册决定了 install 方法需要使用接收的 Vue 对象来注册。细心的童鞋一定会对 vue/dist/vue.common.js
有印象,因为在使用 webpack 的 tree-shaking 的时候,使用 alias 配置 'vue$': vue/dist/vue.common.js,和这个道理是一样的,只是 parcel 帮我们做了这件事。
因为组件源码不是这篇文章的重点,所以 tag.vue 的源码放在最后贴上。
三、下面是最重要的部分:parcel 打包!
首先全局安装 parcel
sudo npm install -g parcel-bundler
不用任何配置文件!
在 package.json 中直接写 scripts:
"scripts": { "demo": "parcel demo/index.html -p 8090 -d lib", "build": "rm -rf lib && parcel build entry.js -d lib --out-file sftctag.min.js --experimental-scope-hoisting", "build:nominify": "rm -rf lib && parcel build entry.js -d lib --out-file sftctag.min.js --no-minify --no-source-maps --experimental-scope-hoisting --no-cache" },
然后直接运行 npm run build
,完事!就是这么快!
注意:如果不使用 tree-shaking 打包的话就会把整个的 vue 源代码也打进去,会增加 65KB 体积!加载一个包就会增加 65 KB,如果是 10 个这样的包,那性能损失真的是太大了。
下面说一个 build 命令里都干了哪些事:
rm -rf lib
每次打包删除 之前的打包目录parcel build entry.js
执行打包命令-d lib
输出目录文件夹名--out-file sftctag.min.js
打包文件名--experimental-scope-hoisting
开启 tree-shaking(parcel 1.9 版本新增特性)build:nominify 用于查看打包出的源代码,新加了几个配置,也说明下:
--no-minify
不压缩代码--no-source-maps
不使用 source-map--no-cache
不使用 .cache
这样整个组件就写完了,parcel 针对这种很小的组件需求,确实是比 webpack 方便很多,但是对于大型项目,开始建议使用 webpack,原因是 parcel 毕竟是小型大包工具很多定制化构建都没有支持,另外现在parcel的相关资料确实不多也不深入。
demo 文件夹:引用 src 中的源码,做一个小 demo,一个是方便看源码的人通过 demo 理解源码。一个是在开发源码时自己做调试。
demo ---> index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <title>sftable</title> </head> <body> <noscript> <strong>We're sorry but sftable doesn't work properly without JavaScript enabled. Please enable it to continue.</strong> </noscript> <div id="app"></div> </body> <script src="./main.js"></script> </html>
demo ---> main.js
import Vue from 'vue'; import App from './App.vue'; import Tag from '../src'; Vue.config.productionTip = false; Vue.use(Tag); new Vue({ render: h => h(App), }).$mount('#app');
demo ---> App.vue
<template> <div id="app"> <div class="container"> <sftc-tag>标签一</sftc-tag> <sftc-tag type="success">标签二</sftc-tag> <sftc-tag type="info">标签三</sftc-tag> <sftc-tag type="warning">标签四</sftc-tag> <sftc-tag type="danger">标签五</sftc-tag> </div> <div class="container"> <sftc-tag closable>标签一</sftc-tag> <sftc-tag closable type="success" @close="handleClose">标签二</sftc-tag> <sftc-tag closable type="info">标签三</sftc-tag> <sftc-tag closable type="warning">标签四</sftc-tag> <sftc-tag closable type="danger">标签五</sftc-tag> </div> <div class="container"> <sftc-tag closable>默认标签</sftc-tag> <sftc-tag size="medium" closable>中等标签</sftc-tag> <sftc-tag size="small" closable>小型标签</sftc-tag> <sftc-tag size="mini" closable>超小标签</sftc-tag> </div> <div class="container"> <sftc-tag v-for="item in list" :key="item" closable type="success" @close="handleClose">标签{{ item }}</sftc-tag> </div> </div> </template> <script> export default { name: 'App', data () { return { list: [1, 2, 3, 4, 5] } }, methods: { handleClose() { this.list.pop(); }, }, } </script> <style> .container { margin-bottom: 30px; } </style>
下一步是发布 npm 包,具体发布 npm 包的方法我就不多介绍了,网上配置文章很多,下面主要说一下 package.json 中的 module 字段配置,Tag 组件的 module 配置是: es/index.js
,下面是 index.js 的代码:
export { default } from '../lib/sftctag.min.js'; export * from '../lib/sftctag.min.js' import '../lib/sftctag.min.css'
很简单就是暴露出了 js 源码并引入需要的 css 文件
package.json 中引入 module 是为了拥抱 ES2015 中的 ES Module,所以也可以享受 tree-shaking 的特性,之前 package.json 一直用 main 字段做入口文件。具体解释可以参考这篇文章:《package.json 中的 Module 字段是干嘛的》
使用 Tag 组件方法:
import Vue from 'vue' import SftcTag from 'sftctag' Vue.use(SftcTag)
<sftc-tag>标签</sftc-tag>
因为 Tag 组件依赖使用者项目的 vue ,所以使用 Tag 组件前必须先引入 vue ,否则会报错。
使用方法和相关 API,最好都写到 README.md 中,方便使用者阅读。
这篇关于探索 parcel(tree-shaking) 构建 vue 插件的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-07-06vue 新建功能多条数据(还没和后端交互)还能看详情 数据是前端缓存到本地吗?-icode9专业技术文章分享
- 2024-05-30React Native常用组件-点击组件
- 2024-05-30uniapp+vue3+uv-ui手机端后台OA管理模板
- 2024-05-29Python网络爬虫的时候json=就是让你少写个json.dumps()
- 2024-05-27React Native常用组件-展示组件
- 2024-05-27React Native常用组件-列表组件
- 2024-05-09vue3开发前端表单缓存自定义指令,移动端h5必备插件
- 2024-05-09React Hooks在class组件中的使用方式
- 2024-03-30[OIDC in Action] 2. 基于OIDC(OpenID Connect)的SSO(纯JS客户端)
- 2024-03-29terraform jsonencode