npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

chengdaohua-ui

v1.0.5

Published

hobby组件

Downloads

2

Readme

微信截图_20220702224234.png

rollup是什么

Rollup 是一个 JavaScript 模块打包器,可以将小块代码编译成大块复杂的代码,例如 library 或应用程序。 我们熟知的Vue、React等诸多知名框架或类库都是通过rollup.js进行打包的。 与Webpack偏向于应用打包的定位不同,rollup.js更专注于Javascript类库打包。 webpack对于代码分割和静态资源导入有着“先天优势”,并且支持热模块替换(HMR),而rollup并不支持。 所以当开发应用时可以优先选择webpack,但是rollup对于代码的Tree-shaking和ES6模块有着算法优势上的支持,若你项目只需要打包出一个简单的bundle包,并是基于ES6模块开发的,可以考虑使用rollup。

模块化

  • CommoneJS:module.exports,require() ,同步引用,编译时加载
  • AMD:非同步加载,前置依赖,浏览器环境要加载资源,实现者 require.js,Node使用;
  • CMD:非同步加载,就近依赖,延迟加载,实现者sea.js ;
  • ESM:exports,import,异步引用,运行时加载,以及Tree-shakeable的特性,因此被广泛使用;
  • UMD:是一种思想,兼容commonjs、AMD、CMD。

commonjs、AMD、CMD、ES6 Module、UMD区别:https://juejin.cn/post/6977604469794013197

快速上手

npm i rollup -g

目录准备(hello world)

├── lib # 编译结果
├── packages # 组件集合
│   └── hpic
├── package.json
└── rollup.config.js # rollup配置

配置

  "name": "chengdaohua-ui",
  "version": "1.0.2",
  "description": "hobby组件",
  "main": "lib/main/index.js",
  "private": false,
  "scripts": {
    // 通过config配置文件运行
    // "build": "rollup -c",
    // 通过直接指令运行
    "build": "rollup src/index.js -f umd -o dist/bundle.js",
    // -w 是指watch监听,实时编译
    "serve": "cross-env NODE_ENV=dev rollup -c -w",
    "serve:prod": "cross-env NODE_ENV=production rollup -c -w",
    "lib": "cross-env NODE_ENV=production rollup -c",
  },
  "author": "chengdaohua",
   // 指定npm push发布的文件
  "files": [
    "package.json",
    "README.md",
    "LICENSE",
    "lib"
  ],
import fs from 'fs';
import path from 'path';
// import autoInstall from '@rollup/plugin-auto-install'; // 自动安装由包导入的依赖项,即使还没有在package.json
import json from '@rollup/plugin-json'; // 将json文件转换为esm模块
import vue from 'rollup-plugin-vue'; // Vue文件编译
import postcss from 'rollup-plugin-postcss'; // css、less、scss编译
import { terser } from 'rollup-plugin-terser'; // js压缩
import commonjs from '@rollup/plugin-commonjs'; // 将 CommonJS 模块转换为 ES6
import { nodeResolve } from '@rollup/plugin-node-resolve'; // 文件resolve,可省略/index.js等
import babel from '@rollup/plugin-babel'; // babel转译es6、es7=>es5
import peerDepsExternal from 'rollup-plugin-peer-deps-external'; // 设置打包外部引用的依赖,不混入
import autoprefixer from 'autoprefixer'; // css兼容,搭配package.json里browserslist使用
import cssnano from 'cssnano'; // 压缩css代码
// import image from '@rollup/plugin-image';  // 图片转base64,配置项未生效,改为@rollup/plugin-url
import url from '@rollup/plugin-url'; // 可以将文件导入为 data-URIs 或 ES Modules,比如复制图片
import copy from 'rollup-plugin-copy'; // 文件拷贝
import replace from '@rollup/plugin-replace'; // 打包时替换
import alias from '@rollup/plugin-alias'; // import alias
import builtins from 'rollup-plugin-node-builtins';
// import globals from 'rollup-plugin-node-globals';

const nodeEnv = process.env.NODE_ENV;
const isProd = process.env.NODE_ENV === 'production'; // 生产环境判断

部分插件介绍

文件引用

// 不配置 @rollup/plugin-node-resolve 插件引入方式
export foo from './foo/index.js'
import bar from './bar/index.js'
// 配置了 @rollup/plugin-node-resolve 插件引入方式
export foo from './foo'
import bar from './bar'
// 对应webpack的设置, 默认寻找--按照设置的格式
resolve: {
  extensions: ['.js', '.jsx', '.vue'],
}

文件复制

// copy文件及目录  https://npmmirror.com/package/rollup-plugin-copy

配置/使用

功能支持

  • [x] 支持外链Vue和安装Vue
  • [x] 支持全量引用和按需引用
  • [x] 支持组件内按需引入第三方组件,例如Vant的van-button组件
  • [x] 支持公共方法自动挂在到Vue.prototype下
  • [x] 支持小图片(<10kb)自动转base64格式
  • [x] 支持umd和es格式输出
  • [x] 支持指定包(Vue,vant等)不编入UI库
  • [x] 支持less、scss编译成css单独抽离打包
  • [x] 支持组件库require引用外部包的方式
  • [x] 支持alias定义,比如js引用路径通过@
  • [x] 支持js和css压缩

组件库示例

示例ui库名称:chengdoahua-ui 发布于npm官方:https://www.npmjs.com/package/chengdaohua-ui 示例组件:hpic

<template>
  <div class="video">
    <van-image :width="width" :height="height" :src="imgUrl || img" />
  </div>
</template>

<script>
import img from "./2.jpg";

export default {
  name: "Hpic",
  props: {
    imgUrl: {
      type: String,
      default: '',
    },
    width: {
      type: [String, Number],
      default: 100,
    },
    height: {
      type: [String, Number],
      default: 100,
    },
  },
  data() {
    return {
      img: img,
    };
  },
};
</script>

示例公共方法:haxios、haddScript

import haxios from './request';
import haddScript from './addScript';

const utils = { haxios, haddScript };
const useFn = function (arr) {
  (arr || []).forEach((e) => {
    Vue.prototype[e] = utils[e];
  });
};
export default useFn;

切换到npm官方源

npm config set registryhttp://registry.npm.taobao.org/

全量引用

// 全量引用
const Vue = window.Vue;  // 外链引用Vue
import Vue from 'vue' // 安装引用Vue
import "chengdaohua-ui";  // 外链引入Vue,则直接引入,自动install所有组件
import {utils} from "chengdaohua-ui";  // 加载工具库
import main from 'chengdaohua-ui'; // 加载所有组件,通过use生效
import 'chengdaohua-ui/lib/main/index.css'; // 全量引入样式
Vue.use(main);
utils(['haxios'])  // 公共方法自动挂在到Vue.prototype
// 直接引用
<Hpic width="400" imgUrl="https://www.rollupjs.com/img/favicon.png"></Hpic>

按需引入

配置babel 新建babel.config.js文件,配置vant和chengdaohua-ui,目的是支持按需加载,原理同element、vant

// 根目录新增文件
module.exports = {
  presets: [
    '@vue/cli-plugin-babel/preset'
  ],
  plugins: [
    ['import', {
      libraryName: 'vant',
      libraryDirectory: 'es',
      style: true
    }, 'vant'],
    [
      'import',
      {
        libraryName: 'chengdaohua-ui',
        customName(name) {
          return `chengdaohua-ui/lib/${name}/${name}-es.js`
        },
        customStyleName(name) {
          return `chengdaohua-ui/lib/${name}/${name}-es.css`
        },
      },
      'chengdaohua-ui',
    ],
  ]
}
import Vue from 'vue'
import {hpic} from "chengdaohua-ui";  // 加载指定组件hpic
import {utils} from "chengdaohua-ui";  // 加载工具库

Vue.use(hpic) // 全局引用单个组件,外链引用可不写
utils(['haxios'])  // 公共方法自动挂在到Vue.prototype
// 直接引用
<Hpic width="400" imgUrl="https://www.rollupjs.com/img/favicon.png"></Hpic>

import {hpic} from "chengdaohua-ui"; // 组件内单独引用单个组件
components: {Hpic}, // 外链引入Vue可不写

优化

  • 减少打包文件的数量
  • 减少不必要的执行函数
  • 增加打包缓存,进行增量打包
  • 由单线程变为多线程

打包时排除外部包的引用

  1. 直接配置

external: ['vue'], // 告诉rollup,不打包vue;将其视为外部依赖

  1. 通过rollup-plugin-peer-deps-external插件排除

package.json里添加peerDependencies,添加打包时要排除的外部引用 设置includeDependencies,所有Dependencies都不会被打包 微信图片_20220703010500.png

完整配置

{
  "name": "chengdaohua-ui",
  "version": "1.0.2",
  "description": "hobby组件",
  "main": "lib/main/index.js",
  "private": false,
  "scripts": {
    "dev": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint --fix",
    "serve": "cross-env NODE_ENV=dev rollup -c -w",
    "serve:prod": "cross-env NODE_ENV=production rollup -c -w",
    "lib": "cross-env NODE_ENV=production rollup -c",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "files": [
    "package.json",
    "README.md",
    "LICENSE",
    "lib"
  ],
  "devDependencies": {
    "@babel/core": "^7.18.6",
    "@babel/eslint-parser": "^7.12.16",
    "@babel/helpers": "^7.18.6",
    "@babel/preset-env": "^7.18.6",
    "@rollup/plugin-alias": "^3.1.9",
    "@rollup/plugin-auto-install": "^2.2.0",
    "@rollup/plugin-babel": "^5.3.1",
    "@rollup/plugin-commonjs": "^22.0.1",
    "@rollup/plugin-image": "^2.1.1",
    "@rollup/plugin-json": "^4.1.0",
    "@rollup/plugin-node-resolve": "^13.3.0",
    "@rollup/plugin-replace": "^4.0.0",
    "@rollup/plugin-url": "^7.0.0",
    "@vue/cli-plugin-babel": "~5.0.0",
    "@vue/cli-plugin-eslint": "~5.0.0",
    "@vue/cli-service": "~5.0.0",
    "autoprefixer": "^10.4.7",
    "babel-plugin-import": "^1.13.5",
    "cross-env": "^7.0.3",
    "cssnano": "^5.1.12",
    "eslint": "^7.32.0",
    "eslint-plugin-vue": "^8.0.3",
    "postcss": "^8.4.14",
    "rollup": "^2.75.7",
    "rollup-plugin-babel": "^4.4.0",
    "rollup-plugin-cleanup": "^3.2.1",
    "rollup-plugin-copy": "^3.4.0",
    "rollup-plugin-node-builtins": "^2.1.2",
    "rollup-plugin-peer-deps-external": "^2.2.4",
    "rollup-plugin-postcss": "^4.0.2",
    "rollup-plugin-terser": "^7.0.2",
    "rollup-plugin-vue": "5.1.9",
    "vue-template-compiler": "^2.7.0"
  },
  "dependencies": {
    "axios": "^0.27.2",
    "babel-eslint": "^10.1.0",
    "core-js": "^3.8.3",
    "vant": "^2.12.48",
    "vue": "^2.7.0",
    "vue-runtime-helpers": "^1.1.2"
  },
  "peerDependencies": {
    "vue": "^2.7.0"
  },
  "browserslist": [
    "defaults",
    "not ie < 8",
    "last 2 versions",
    "> 1%",
    "iOS 7",
    "last 3 iOS versions"
  ]
}
import fs from 'fs';
import path from 'path';
// import autoInstall from '@rollup/plugin-auto-install'; // 自动安装由包导入的依赖项,即使还没有在package.json
import json from '@rollup/plugin-json'; // 将json文件转换为esm模块
import vue from 'rollup-plugin-vue'; // Vue文件编译
import postcss from 'rollup-plugin-postcss'; // css、less、scss编译
import { terser } from 'rollup-plugin-terser'; // js压缩
import commonjs from '@rollup/plugin-commonjs'; // 将 CommonJS 模块转换为 ES6
import { nodeResolve } from '@rollup/plugin-node-resolve'; // 文件resolve,可省略/index.js等
import babel from '@rollup/plugin-babel'; // babel转译es6、es7=>es5
import peerDepsExternal from 'rollup-plugin-peer-deps-external'; // 设置打包外部引用的依赖,不混入
import autoprefixer from 'autoprefixer'; // css兼容,搭配package.json里browserslist使用
import cssnano from 'cssnano'; // 压缩css代码
// import image from '@rollup/plugin-image';  // 图片转base64,配置项未生效,改为@rollup/plugin-url
import url from '@rollup/plugin-url'; // 可以将文件导入为 data-URIs 或 ES Modules,比如复制图片
import copy from 'rollup-plugin-copy'; // 文件拷贝
import replace from '@rollup/plugin-replace'; // 打包时替换
import alias from '@rollup/plugin-alias'; // import alias
import builtins from 'rollup-plugin-node-builtins';
// import globals from 'rollup-plugin-node-globals';

const nodeEnv = process.env.NODE_ENV;
const isProd = process.env.NODE_ENV === 'production'; // 生产环境判断

// 公共插件配置
const plugins = [
  // globals(),
  builtins(),
  // autoInstall(),
  peerDepsExternal({
    // includeDependencies: !isProd, // speed up 排除Dependencies所有依赖
  }),
  json(),
  nodeResolve(),
  commonjs(),
  vue({
    // Dynamically inject css as a <style> tag
    css: false,
    // Explicitly convert template to render function
    compileTemplate: true
  }),
  postcss({
    // 把 css 插入到 style 中
    // inject: true,
    // 把 css 放到和js同一目录
    extensions: ['.css', '.less', 'scss'],
    extract: true,
    plugins: [autoprefixer(), isProd ? cssnano() : null]
  }),
  babel({
    // presets必须设置子这里,.babelrc文件里没生效
    presets: ['@babel/preset-env'],
    plugins: [
      ['import', {
        libraryName: 'vant',
        libraryDirectory: 'es',
        style: true
      }, 'vant']
    ],
    // babelHelpers: 'bundled',
    exclude: 'node_modules/**'
  }),
  // image({
  //   output: path.resolve(__dirname, 'lib'), // 打包后的文件
  //   extensions: /\.(png|jpg|jpeg|gif|svg)$/,
  //   limit: 1024 * 10, // 文件大小的限制(字节)。当一个文件没有超过限制时,它将被转换为 base64字符串,否则,它将被复制到output下
  //   exclude: 'node_modules/**',
  // }),
  url({
    destDir: `./lib/assets/images`,
    publicPath: '../assets/images/',
    limit: 1024 * 10 // 超过10kb复制,否则转base64
  }),
  alias({
    resolve: ['.js'],
    entries: [
      // { find: 'utils', replacement: '../../../utils' },
      { find: '@', replacement: './packages' }
    ]
  }),
  copy({
    targets: [
      // { src: 'src/index.html', dest: 'lib/public' },
      // {
      //   src: ['assets/fonts/arial.woff', 'assets/fonts/arial.woff2'],
      //   dest: 'lib/public/fonts',
      // },
      // { src: 'assets/images/**/*', dest: 'lib/public/images' },
    ]
  }),
  replace({
    preventAssignment: true,
    'process.env.NODE_ENV': JSON.stringify(nodeEnv)
  })
];

// 如果是生产环境,开启压缩
isProd && plugins.push(terser());

// packages 文件夹路径
const root = path.resolve(__dirname, 'packages');
module.exports = fs
  .readdirSync(root)
  // 过滤,只保留文件夹
  .filter((item) => fs.statSync(path.resolve(root, item)).isDirectory())
  // 为每一个文件夹创建对应的配置
  .map((item) => {
    // const pkg = require(path.resolve(root, item, 'package.json'));
    return {
      input: path.resolve(root, item, 'index.js'),
      output: [
        // {
        //   exports: 'auto',
        //   file: path.resolve(root, item, `../../lib/cjs/${item}.js`),
        //   format: 'cjs',
        // },
        {
          exports: 'auto',
          file: path.join(root, item, `../../lib/${item}/${item}-es.js`),
          format: 'es'
        },
        {
          exports: 'auto',
          file: path.join(root, item, `../../lib/${item}/index.js`),
          format: 'umd',
          name: item,
          globals: {
            vue: 'Vue' // 跟external 配套使用,指明global.Vue即是外部依赖vue
          }
        }
      ],
      plugins: plugins,
      // external: ['vue'], // 告诉rollup,不打包vue;将其视为外部依赖
      global: {
        jquery: '$', // 告诉rollup 全局变量$即是jquery
        vue: 'Vue' // 跟external 配套使用,指明global.Vue即是外部依赖vue
      }
    };
  });

参考文档

rollup官方地址:https://rollupjs.org/guide/zh/ rollup打包加速:http://www.redream.cn/2021/01/25/rollup%E6%89%93%E5%8C%85%E5%8A%A0%E9%80%9F/