通过rollup打包vue组件库

项目文件目录

├── src
|   ├── components
|   |   ├── compon1.vue
|   |   ├── compon2.vue
|   |   ├── compon3.vue
|   ├── app.vue
|   ├── main.js
├── index.js
├── rollup.config.js
├── package.json

rollup.config.js

// rollup-plugin-vue插件需指定版本,@5.1.9对应的是vue2.x,@6.0.0以上对应的是vue3.x
import vue from "rollup-plugin-vue";
// import resolve from "rollup-plugin-node-resolve";
import resolve from "@rollup/plugin-node-resolve";
// import babel from "rollup-plugin-babel";
import babel from "@rollup/plugin-babel";
// import commonjs from "rollup-plugin-commonjs"
import commonjs from "@rollup/plugin-commonjs";
import json from '@rollup/plugin-json'
// import image from "@rollup/plugin-image"
// 处理css需要用到的插件是rollup-plugin-postcss。它支持css文件的加载、css加前缀、css压缩、对scss/less的支持等等
// import postcss from 'rollup-plugin-postcss'
// autoprefixer插件来给css3的一些属性加前缀--webkid,npm i autoprefixer@8.0.0 --D

const config = {
  input: "./index.js", // 必须,入口文件
  output: {
    // 必须,输出文件 (如果要输出多个,可以是一个数组)
    // exports: "named", // 输出多个文件
    globals: {
      vue: "Vue", // 告诉rollup全局变量Vue即是vue
    },
  },
  external:['lodash'] //告诉rollup不要将此lodash打包,而作为外部依赖
  plugins: [
    // 引入的插件在这里配置
    resolve({
      preferBuiltins: true,
      browser: true
    }),
    vue({
      css: true,
      compileTemplate: true
    }),
    babel({
      exclude: "**/node_modules/**",
      babelHelpers: "runtime",
    }),
    commonjs(),
    json()
    // image()
  ],
};
export default config;

index.js

// Import vue component
import Compon1 from "./src/components/compon1.vue";
import Compon2 from "./src/components/compon2.vue";
import Compon3 from "./src/components/compon3.vue";
import  './flexible';// 为适配移动端用

const components = [
  Compon1,
  Compon2,
  Compon3
];

const install = function (Vue) {
  components.forEach((component) => {
  // 组件compon1内部必须定义name
    Vue.component(component.name, component);
  });
};

if (typeof window !== "undefined" && window.Vue) {
  install(window.Vue);
}

export default { 
	install,
	// 按需导出
	Compon1,
  	Compon2,
  	Compon3
 };

package.json配置打包命令

{
  "name": "vue2_demo",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint",
    "build:es": "rollup -c --format es --file dist/components.esm.js"
  },
  "dependencies": {
    "axios": "^1.3.4",
    "core-js": "^3.6.5",
    "lodash": "^4.17.21",
    "vue": "^2.6.11",
    "vue-router": "^3.2.0",
    "vuex": "^3.4.0"
  },
  "devDependencies": {
    "@babel/core": "^7.21.0",
    "@rollup/plugin-babel": "^6.0.3",// √
    "@rollup/plugin-commonjs": "^24.0.1",// √
    "@rollup/plugin-image": "^3.0.2",// √
    "@rollup/plugin-json": "^6.0.0",// √
    "@rollup/plugin-node-resolve": "^13.3.0",// √
    "@vue/cli-plugin-babel": "~4.5.15",
    "@vue/cli-plugin-eslint": "~4.5.15",
    "@vue/cli-plugin-router": "~4.5.15",
    "@vue/cli-plugin-vuex": "~4.5.15",
    "@vue/cli-service": "~4.5.15",
    "@vue/eslint-config-prettier": "^6.0.0",
    "babel-eslint": "^10.1.0",
    "eslint": "^6.7.2",
    "eslint-plugin-prettier": "^3.3.1",
    "eslint-plugin-vue": "^6.2.2",
    "less": "^3.0.4",
    "less-loader": "^5.0.0",
    "prettier": "^2.2.1",
    "rollup": "^2.79.1",// √
    "rollup-plugin-babel": "^4.4.0",// √
    "rollup-plugin-commonjs": "^10.1.0",// √
    "rollup-plugin-node-resolve": "^5.2.0",// √
    "rollup-plugin-terser": "^7.0.2",// √
    "rollup-plugin-vue": "^5.1.9",// √
    "vue-template-compiler": "^2.6.11"//配合rollup-plugin-vue工作
  }
}
// 推荐使用@rollup/xx开头的依赖包

main.js里注册use

import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import store from "./store";
import YTUI from "./assets/components.esm";

Vue.config.productionTip = false;
Vue.use(YTUI);

new Vue({
  router,
  store,
  render: (h) => h(App),
}).$mount("#app");

这样就可以在所有页面直接使用啦

<template>
  <div class="home">
    <HelloWorld msg="Welcome to Your Vue.js App" />
    <compon1 />
    <compon2 />
    <compon3 />
  </div>
</template>

兼容移动端适配

flexible.js


 ;(function(win, flexible = {}) {
  var doc = win.document;
  var docEl = doc.documentElement;
  var metaEl = doc.querySelector('meta[name="viewport"]');
  var flexibleEl = doc.querySelector('meta[name="flexible"]');
  var dpr = 0;
  var scale = 0;
  var tid;

  if (metaEl) {
      console.warn('将根据已有的meta标签来设置缩放比例');
      var match = metaEl.getAttribute('content').match(/initial\-scale=([\d\.]+)/);
      if (match) {
          scale = parseFloat(match[1]);
          dpr = parseInt(1 / scale);
      }
  } else if (flexibleEl) {
      var content = flexibleEl.getAttribute('content');
      if (content) {
          var initialDpr = content.match(/initial\-dpr=([\d\.]+)/);
          var maximumDpr = content.match(/maximum\-dpr=([\d\.]+)/);
          if (initialDpr) {
              dpr = parseFloat(initialDpr[1]);
              scale = parseFloat((1 / dpr).toFixed(2));
          }
          if (maximumDpr) {
              dpr = parseFloat(maximumDpr[1]);
              scale = parseFloat((1 / dpr).toFixed(2));
          }
      }
  }

  if (!dpr && !scale) {
      var isAndroid = win.navigator.appVersion.match(/android/gi);
      var isIPhone = win.navigator.appVersion.match(/iphone/gi);
      var devicePixelRatio = win.devicePixelRatio;
      if (isIPhone) {
          // iOS下,对于2和3的屏,用2倍的方案,其余的用1倍方案
          if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) {
              dpr = 3;
          } else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)){
              dpr = 2;
          } else {
              dpr = 1;
          }
      } else {
          // 其他设备下,仍旧使用1倍的方案
          dpr = 1;
      }
      scale = 1 / dpr;
  }

  docEl.setAttribute('data-dpr', dpr);
  if (!metaEl) {
      metaEl = doc.createElement('meta');
      metaEl.setAttribute('name', 'viewport');
      metaEl.setAttribute('content', 'initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');
      if (docEl.firstElementChild) {
          docEl.firstElementChild.appendChild(metaEl);
      } else {
          var wrap = doc.createElement('div');
          wrap.appendChild(metaEl);
          doc.write(wrap.innerHTML);
      }
  }

  function refreshRem(){
      var width = docEl.getBoundingClientRect().width;
      if (width / dpr > 540) {
          width = 540 * dpr;
      }
      var rem = width / 10;
      docEl.style.fontSize = rem + 'px';
      flexible.rem = win.rem = rem;
  }

  win.addEventListener('resize', function() {
      clearTimeout(tid);
      tid = setTimeout(refreshRem, 300);
  }, false);
  win.addEventListener('pageshow', function(e) {
      if (e.persisted) {
          clearTimeout(tid);
          tid = setTimeout(refreshRem, 300);
      }
  }, false);

  if (doc.readyState === 'complete') {
      doc.body.style.fontSize = 12 * dpr + 'px';
  } else {
      doc.addEventListener('DOMContentLoaded', function(e) {
          doc.body.style.fontSize = 12 * dpr + 'px';
      }, false);
  }


  refreshRem();

  flexible.dpr = win.dpr = dpr;
  flexible.refreshRem = refreshRem;
  flexible.rem2px = function(d) {
      var val = parseFloat(d) * this.rem;
      if (typeof d === 'string' && d.match(/rem$/)) {
          val += 'px';
      }
      return val;
  }
  flexible.px2rem = function(d) {
      var val = parseFloat(d) / this.rem;
     // if (typeof d === 'string' && d.match(/px$/)) {
     //    val += 'rem';
     // }
      return val;
  }

})(window, window['flexible'] || (window['flexible'] = {}));

compen1.vue

<template>
  <div>
    <h2 :style="{ width: wToRem, height: addUnit(height)}">component1</h2>
  </div>
</template>

<script>
import Axios from "axios";// 用到的依赖会自动打包进去
// import Axios from 'axios/dist/axios';
export default {
  name: "Compon1",
  props: {
    width: String | Number, // 100 or '100px'
    height: String | Number,
  },
  created() {
    console.log("Compon1",document.documentElement.clientWidth / 10 + "px");
    Axios.get(
      "https://mock.presstime.cn/mock/621ee0b1a977410016aaae08/yangtao/mock"
    ).then(({data}) => {
      console.log(data);
    });
  },
  computed: {
    wToRem() {
      return flexible.px2rem(this.width) / 2 + "rem";
    },
    hToRem() {
      return flexible.px2rem(this.height) / 2 + "rem";
    },
  },
  methods: {
    testFn(data) {
      if (/\px$/.test(data)) return data.replace(/px/g, "");
      return data;
    },
    addUnit(data) {
		return flexible.px2rem(data) / 2 + "rem";
	}
  },
};
</script>

<style lang="less" scoped>
@import "../assets/style.less";
</style>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

C+ 安口木

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值