
Research
/Security News
Miasma Mini Shai-Hulud Hits ImmobiliareLabs npm Packages
Miasma Mini Shai-Hulud hits @immobiliarelabs Backstage plugins, targeting GitLab and LDAP auth packages on npm.
约定大于配置的极速 Web 应用打包工具,支持 .vue 文件,生产使用 Rollup 打包
仅供学习研究,请勿用于生产
【Github】 https://github.com/chjtx/pr1
【 码 云 】 https://gitee.com/chenjianlong/pr1
对比环境 华为荣耀 MagicBook Windows 10 家庭版 i5 8G 64位 联通4G热点 30多个组件的小型 Vue 项目
| 飘刃 | Vue-CLI | |
|---|---|---|
| 工具版本 | piaoren@0.1.1 | @vue/cli@3.6.3 |
| 依赖包数 | 487 | 689 |
| 安装命令 | npm i -g piaoren | npm i -g @vue/cli |
| 安装时间 | 38s | 1m 42s |
| 支持编码 | Pug Sass ES6+ | Pug Sass Less Stylus ES6+ TypeScript |
| 创建项目 | pr1 init 只需要填项目名称 | vue create/vue init 需要填选多项 |
| 启动命令 | pr1 start | vue serve |
| 启动时间 | 2s 与项目内容多少无关 | 6.8s 项目内容多少决定 |
| 热更响应 | 支持更新 css 和刷新页面 两种方式,不支持 js 更新 更新 js 需要刷新页面 响应速度 立即 | 支持 css 和 js 更新,vue 组件更新 有点鸡肋,很大概率需要手动更新 才能看到预期效果,每次变化都需 要编译,响应速度 稍慢 |
| 打包工具 | Rollup | Webpack |
| 打包时间 | 5s 项目内容多少决定 | 10s 项目内容多少决定 |
| 静态资源 | 暂只支持.和/开头的静态资源 | 支持.、/、@和~开头的静态资源 |
| 多页应用 | 无需配置 | 需要配置 pages |
| 插件支持 | Rollup 插件规范 | Webpack 插件规范 |
| 单元测试 | 暂不支持 | 可选 |
总结:飘刃安装时间、启动速度、响应速度、打包时间都优于 Vue-CLI,但是配置方面不及 Vue-CLI 丰富。中小型无需配置的项目选择飘刃,大中型需要多方面资源配合的项目选择 Vue-CLI。
npm i -g piaoren
把飘刃安装到全局,任意目录都可以运行飘刃的命令 pr1
pr1 init
? Project name: # 项目名称至少两个字符,由大小写字母、中划线、下划线,及数字组成,数字不能为首字符
? Project description: # 可不填
将会自动生成项目名称命名的文件夹,包含若干工程文件
进入工程目录,执行以下命令开启开发模式
npm run dev
// main.js
import Vue from 'vue/dist/vue.esm.browser.js'
import Layout from './pages/Layout.vue'
// eslint-disable-next-line no-new
new Vue({
el: '#app',
components: {
Layout
},
template: '<Layout/>'
})
<!-- pages/Layout.vue -->
<template lang="pug">
div
div.top
input(v-model="text")
button(@click="submit") 添加
ul
Item(v-for="(i, k) in items" :name="i" :key="k")
</template>
<script>
import Item from './Item.js'
export default {
components: {
Item
},
data () {
return {
text: '',
items: []
}
},
methods: {
submit () {
this.items.push(this.text)
this.text = ''
}
}
}
</script>
<style lang="sass" scoped>
$bg: #ccc;
.top {
padding: 20px;
background: $bg;
}
</style>
// pages/Item.js
import html from './Item.html'
export default {
template: html,
props: {
name: String
}
}
<!-- pages/Item.html -->
<li class="item">{{ name }}</li>
<style scoped>
.item {
background: #eee;
}
</style>
在浏览器访问 http://localhost:8686/
以上例子演示了两种写 Vue 组件的方法
一、使用 .vue 文件,目前 .vue 文件只支持普通的 html/css/js 和 sass/pug ,不支持 less/typescript 等。注意 Layout.vue 的 pug ,首行第一个位置不能是空格,即不能缩进。
二、使用 html 和 js 两个文件写 Vue 组件,如果存在同路径同名的两个文件,例:Component.html 和 Component.js,则飘刃会把这两个文件处理成 Vue 组件。需要注意的是,这种方式的 html 文件不包括 script ,所以不需要 template 标签,直接写 div ,也不支持 pug。
开发完成后,使用以下命令打包
npm run build
打包完成后可在 dist 目录双击 index.html 到浏览器访问,如果项目包含 ajax 请求,file:// 协议文件无法跨域,可以在 dist 目录运行 pr1 start 8080 开启飘刃服务,在浏览器访问 http://localhost:8080/
# 创建项目,初始化工程文件
pr1 init
# 开启飘刃服务,在哪个目录开启,哪个目录就是根站点
# 可在浏览器访问该站点文件,相当于微型静态服务器
# 将会拦截所有带 pr1_module=1 参数的 url 进行文件处理
# 用于开发环境
pr1 start [port] [config]
# 示例
pr1 start # 默认 8686 端口,工程根目录的 pr1.config.js 配置文件
pr1 start 8080 # 指定 8080 端口
pr1 start --config="./config.js" # 指定 ./config.js 配置文件
pr1 start 8080 --config="./config.js" # 指定端口和配置文件
# 使用 build 命令打包,必须指定入口文件,只能是 html 和 js 文件
# 可以同时打包多个模块
# 如果是 html 文件,将会自动解决 html 里的入口文件及复制静态资源
# 如果是 js 文件,只会解决该 js 文件及其依赖,不会复制静态资源
# 入口文件目录与打包后的文件目录结构相同
pr1 build [entry] [config]
# 示例
pr1 build index.html # 使用默认配置文件打包
pr1 build index.html --config="./config.js" # 使用指定配置文件
pr1 build index.html detail.html tools.js # 同时打包3个文件
pr1 build index.html detail.html tools.js --config="./config.js" # 使用指定配置打包3个文件
pr1 build page1/index.html page2/index.html # 在打包后也会保持同样结构
// pr1.config.js
const nodeResolve = require('rollup-plugin-node-resolve')
require('colors')
module.exports = {
// vendor 子项的第一个值将会整合到 rollup 的 external
// [0]是开发环境用的,[1]是生产环境用的,如果没有[1]生产环境也用[0]
vendor: [
['vue/dist/vue.esm.browser.js', 'vue/dist/vue.runtime.min.js']
],
// true 表示存在同级目录且同名的 html 和 js 文件会被关联到一起
// 转成 Vue render 组件提高性能,仅生产环境起作用
html2VueRender: true,
// 热更新 true or reload,如果是字符串 reload,将会刷新浏览器而非 .vue 组件
hot: true,
// dist 打包后文件输出目录,路径应相对于当前配置文件
dist: '',
// static 静态文件,路径应相对于 html 入口文件
static: [],
// rollup 选项,必须有
rollupConfig: {
// 定义了 vendor,再定义 globals,这样 rollup 会把相关的 vendor 转换成全局变量作为外部资源处理
globals: {
'vue/dist/vue.esm.browser.js': 'Vue'
},
plugins: [
// rollup-plugin-node-resolve 用于解决引用 node_modules 资源路径
nodeResolve()
]
},
// babel 选项,不提供将不会进行转码,不使用 uglify 压缩时,可安装 babel 的 minify 插件压缩
babelConfig: {
presets: [
[
'@babel/env', {
modules: false,
targets: {
ie: '9',
chrome: '49'
}
}
]
]
},
// uglify 选项,不提供将不会压缩,如果 babel 转码后仍存在 ES6+ 代码,uglify 解释不了将会压缩失败
uglifyConfig: {
toplevel: true
},
// 打包前的钩子
beforeBuild: async function (originDir) {
console.log(`开始打包:`.green + `${originDir}`.cyan)
},
// 打包后的钩子
afterBuild: async function (distDir) {
console.log(`完成打包:`.green + `${distDir}`.cyan)
}
}
飘刃会拦截所有带有 pr1_module=1 参数的 url ,并处理对应的文件资源,目前只会处理 .vue .html .js 3种文件
把 import/export 转换成 async/await 让浏览器可以支持引入除 js 外的其它资源
飘刃会把非 js 资源通过 rollup 的插件转换成 js 资源再传到浏览器,开发环境只会调用 rollup 插件的 resolveId 和 transform 方法
import/export 转换关系如下:
// import 规则
import { a, b, c } from './util.js' => const { a, b, c } = await _import('./util.js')
import { abc as a, efg as b } from './util.js' => const { abc: a, efg: b } = await _import('./util.js')
import a from './util.js' => const { default: a } = await _import('./util.js')
import './util.js' => await _import('./util.js')
import * as a from './util.js' => const a = await _import('./util.js')
import a, { efg as b, c } from './util.js' => const { default: a, efg: b, c } = await _import('./util.js')
// export 规则
export var a = 'xxx' => var a = exports.a = 'xxx'
export { a, b, c } => Object.assign(exports, {a, b, c})
export function a () {} => exports.a = a; function a () {}
export default a => exports.default = a
export { abc as a } => Object.assign(exports, {a: abc} = { a })
export class e {} => exports.e = e; class e {}
export { default as d } from './util.js' => Object.assign(exports, await (async () => { const { default: d
} = await _import('./util.js'); return { d }})())
支持两种静态资源路径 以 / 开头和以 . 开头
/ 开头的资源路径相对站点根目录. 开头的资源路径相对当前引用的文件如下目录结构
src/
|-- index.html
|-- static/
|-- images/
|-- a.png
|-- pages/
|-- one/
|-- two/
|-- three/
|-- a.vue # background-url: /static/images/a.png
|-- b.html # img src="../static/images/a.png"
|-- b.js
绝对路径和相对路径都是引用同一张图片
支持组件多 style ,组件内 style 均为组件内样式,带 scoped 不会影响子组件,不带 scoped 会影响子组件,全局样式请用 link 标签引入
飘刃处理多面应用非常简单,如下目录结构
src/
|-- page1/
|-- index.html
|-- page2/
|-- index.html
|-- page3/
|-- index.html
开发环境,在 src 目录执行 pr1 start
在浏览器分别访问
生产环境,在 src 目录执行 pr1 build page1/index.html page2/index.html page3/index.html
在 dist 目录会保持以下目录结构
dist/
|-- page1/
|-- index.html
|-- page2/
|-- index.html
|-- page3/
|-- index.html
目前只支持引入 .ts 文件,.vue 组件的 type=ts 暂不支持
# 安装
npm i rollup-plugin-typescript typescript tslib
修改 pr1.config.js 添加 typescript 插件
const typescript = require('rollup-plugin-typescript')
// ...
module.exports = {
rollupConfig: {
// ...
plugins: [
typescript({
target: 'ESNext',
})
// ...
]
},
// ...
}
如下示例:
doSome(data => {
// pr1 ignore++
console.info(`调试信息:${data}`)
// pr1 ignore--
doIt(data)
})
// pr1 ignore++到// pr1 ignore--的代码在生产环境会被删除
doSome(data => {
doIt(data)
})
rollup-plugin-node-resolve 插件解决@import 导入是相对于当前 sass 所在文件的,只支持 @import sass,暂不支持自动拷贝 @import css 的文件<style lang="sass" scoped>、<style lang="sass">、<style scoped>,不允许<style scoped lang="sass">,同理如果要使用 pug ,必须书写成<template lang="pug">,不允许多空格或少空格<template>
<div class="top">
<div class="abc">123</div>
</div>
</template>
<style>
/* 不带 scoped 必须使用 this 表示最外层 dom 选择器 */
this {
background: #efefef;
}
.abc {
font-size: 20px;
}
</style>
<style scoped>
/* 带 scoped 可以使用最外层 dom 的 class 来做选择器 */
.top {
font-size: 22px;
}
</style>
如果同目录存在同名的 html 和 js 文件并开启 html2VueRender 选项,默认开启,则视为 Vue 组件,打包时会自动关联转成 render 函数。同名 js 文件只能用 template: html,不能用其它变量
// html/js 的 Vue 组件只能用 html 作为变量名引入同名 html 文件
import html from './sameName.html'
export default {
template: html
}
在 html 里的 <img src="./.."> 和 css 里的 background:url(./..) 小于 4k 的图片会自动转为 base64,无法自动解决的静态资源需要手动在 static 选项添加资源目录名或具体资源文件名,如下示例的资源不能自动处理
<img v-for="i in images" :src="i.src">
js 文件或 vue 文件如果在行首要输入 import xxx from export default 这类字符串需要转义,或者使用字符串拼接不能让飘刃转换 import 和 export 的规则命中
const str = `
import xxx from 'a.js'
export default { b: 1 }
`
// 要写成
const str = `
\u0069mport xxx from 'a.js'
\u0065xport default { b: 1 }
`
// 或
const str = `
i` + `mport xxx from 'a.js'
e` + `xport default { b: 1 }
`
运行 pr1 start 出错
Error: listen EADDRINUSE :::8686
at Server.setupListenHandle [as _listen2] (net.js:1335:14)
at listenInCluster (net.js:1383:12)
8686 端口被占用,解决方案:指定端口运行或先关闭占用 8686 端口的程序
运行 pr1 build 出错
(node:20976) UnhandledPromiseRejectionWarning: Error: EBUSY: resource busy or locked, rmdir 'D:\xx\dist'
dist 目录繁忙或锁定,无法删除。解决方案:检查 dist/index.html 是否在浏览器中打开,将其关闭再重新打包
### v0.3.16 (2020-04-11)
exports { default } from 'xxx'解释报default是保留字的错误问题### (2019-12-30)
v0.3.15
class a extend b格式解释错误的问题v0.3.14
export * from 'xxx'格式module.exports= exports 被修改的问题export { a, b as bb }带有 as 和无 as 混合格式导出### v0.3.13 (2019-12-07)
### v0.3.12 (2019-10-29)
### v0.3.11 (2019-10-04)
### v0.3.10 (2019-08-12)
pr1 start报错的问题### v0.3.9 (2019-06-28)
### (2019-06-02)
v0.3.8
export const a = 在本文件不起作用的 bugv0.3.7
v0.3.6
添加模块 rollup-plugin-paths 路径别称支持
添加支持 node_modules 模块无后缀名资源的引入
修复 export { 以 { 结尾的导出语法解释错误
修复文本内容带 $& $$ 等特殊字符替换文本出错的 bug
### v0.3.5 (2019-05-26)
### (2019-05-25)
v0.3.4
v0.3.3
### (2019-05-24)
v0.3.2
v0.3.1
### v0.3.0 (2019-05-23)
### (2019-05-22)
v0.2.13
v0.2.12
v0.2.11
hot: 'style' 选项### v0.2.10 (2019-05-12)
export default Vue.extend({ 等语法### v0.2.9 (2019-05-08)
### (2019-05-06)
v0.2.8 修复 v0.2.1 优化项目文件结构产生引用 某些 js 路径错误的问题
v0.2.7
### v0.2.6 (2019-05-04)
export function abc 开发阶段同文件其它函数访问不了 abc() 的问题### (2019-05-02)
### v0.2.1 (2019-04-30)
resolveId 方法### v0.2.0 (2019-04-29)
import a, { b, c } ... 和 export { a } from ... 语法@import 导入路径问题### v0.1.1 (2019-04-26)
### v0.0.10 (2019-04-24)
支持作者继续维护更新,编写更多教程和使用技巧。如果有足够的支持,飘刃将来将会支持 React、TypeScript、异步模块等等。
支持方式
打赏1块几毛钱,让作者不用去天桥底蹲位
MIT
FAQs
We found that piaoren demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
/Security News
Miasma Mini Shai-Hulud hits @immobiliarelabs Backstage plugins, targeting GitLab and LDAP auth packages on npm.

Security News
Rolldown paused Rust React Compiler integration after a 5MB binary size increase raised concerns about shipping React-specific code to all Vite users.

Security News
/Research
Mini Shai-Hulud expands into the Go ecosystem after hitting LeoPlatform npm packages and targeting GitHub Actions workflows.