rollup 开发vue组件库及umd SDK 问题总结

需求:构建vue组件库成为js sdk 浏览器直接运行

umd是通用格式,兼容各种环境

对js模块化规范了解===>:JS模块化总结

rollup使用过程中遇到的各种问题

https://www.dazhuanlan.com/2019/10/22/5dae8543f0ec1/

rollup开发依赖包(npm library),解决引入外部依赖失败的有效方法

rollup 开发vue组件库及umd SDK 问题总结_第1张图片

import nodePolyfills from 'rollup-plugin-node-polyfills';
  plugins: [
    vue(),
    nodePolyfills(),
]

(!) Missing global variable name

image.png

出现这个问题的原因是rollup通过external + output.globals来标记外部依赖,所以需要在配置文件的output输出配置属性中添加globals属性,指定与外部模块相对应的浏览器全局变量名称,如:

globals: {
    "vue": "vue" // 指明 global.vue 即是外部依赖 vue
}

要是按照以上配置后问题还没解决,还有一个可能是在引入组件或者自己写js模块时,没有使用相对路径引入,比如你想在 src/index.js 中引入组件 src/components/Test.vue

// 应该这样引入
import Test from './components/Test.vue'
// 而不是
import Test from 'components/Test.vue'

(!) Unused external imports

image.png

(!) Circular dependencies

image.png

  • Unused external imports 这个问题是因为import了uglify但是没用,忽略
  • Circular dependencies 因为历史原因,库中有使用yss-biz这个alias,后面通过rollup-plugin-includepaths重新定义这个别名的指向,最终出现循环引用,忽略
  • this has been rewritten to undefined 这是因为库中写的代码不正确用了箭头函数然后还绑定了this忽略
  • Unused external imports 这个是因为导入的内容没有使用,忽略

 

module is not defined

image.png

https://github.com/rollup/rollup/issues/2661

image.png

 

image.png

rollup 开发vue组件库及umd SDK 问题总结_第2张图片

(!) `this` has been rewritten to `undefined`

rollup 开发vue组件库及umd SDK 问题总结_第3张图片

 

https://stackoverflow.com/questions/61827807/svelte-i18n-svelte-rollup-compiler-warning-this-has-been-rewritten-to-unde

 

rollup 开发vue组件库及umd SDK 问题总结_第4张图片

 

common.js 在plugin位置尽量在上面,作者本人的插件顺序如下

const plugins = [
  vue({
    css: true,
    compileTemplate: true,
    include: /\.vue$/,
    target: 'browser',
  }),
  css(),
  nodeResolve({
    preferBuiltins: true,
    browser: true,
    jsnext: true,
    main: true,
  }),
  commonjs(),
  alias({
    resolve: ['.jsx', '.js', '.vue'], //optional, by default this will just look for .js files or folders
    entries: [
      { find: '@', replacement: './package/deleteVersion-vue-build/packages' }, //the initial example
    ],
  }),
  nodePolyfills(),
  globals(),
  replace({
    'process.env.NODE_ENV': JSON.stringify(env),
  }),
  postcss({
    modules: false,
    extensions: ['.less', '.css', '.scss'],
    plugins: [
      nested(),
      simpleVars(),
      cssnext({ warnForDuplicates: false }),
      cssnano(),
    ],
  }),
  builtins(),
  json(),
  babel({
    exclude: 'node_modules/**',
    runtimeHelpers: true,
  }),
];

 

image.png

https://github.com/vueComponent/ant-design-vue/issues/2745

rollup 开发vue组件库及umd SDK 问题总结_第5张图片

 

npm uninstall babel-plugin-import

 

WARNING (@babel/preset-env): We noticed you're using the `useBuiltIns` option without declaring a core-js version. Currently, we assume version 2.x when no version is passed. Since this default version will likely change in future versions of Babel, we recommend explicitly setting the core-js version you are using via the `corejs` option.

You should also be sure that the version you pass to the `corejs` option matches the version specified in your `package.json`'s `dependencies` section. If it doesn't, you need to run one of the following commands:

  npm install --save core-js@2    npm install --save core-js@3
  yarn add core-js@2              yarn add core-js@3
警告(@babel/pre -env):我们注意到你使用了' useBuiltIns '选项而没有声明一个core-js版本。目前,我们假设版本2。x表示没有通过任何版本。因为这个默认版本可能会在Babel的未来版本中改变,我们建议通过“corejs”选项显式设置你正在使用的core-js版本。
您还应该确保传递给“corejs”选项的版本与“包”中指定的版本匹配。json的“依赖性”部分。如果没有,则需要运行以下命令之一:
npm install——save core-js@2 npm install——save core-js@3
yarn add core-js@2 yarn add core-js@3

image.png

 

这个错误定位后发现与rollup-plugin-uglify插件有关,rollup-plugin-uglify不能压缩es6的代码文件。rollup-plugin-uglify的官方文档是说

Note: uglify-js is able to transpile only es5 syntax. If you want to transpile es6+ syntax use terser instead

顺着这个思路有两种解决方法,一只要把es6的代码用babel转换成es5即可。二使用rollup-plugin-terser插件代替rollup-plugin-uglify

安装rollup-plugin-terser

yarn add rollup-plugin-terser --dev

使用rollup-plugin-terser

import { rollup } from "rollup";
import { terser } from "rollup-plugin-terser";
rollup({
  input: "main.js",
  plugins: [terser()]
});

antd 组件源码错误

 

rollup 开发vue组件库及umd SDK 问题总结_第6张图片

rollup 开发vue组件库及umd SDK 问题总结_第7张图片

    switch (e) {
            case 'fill':
              return c + '-fill';
            case 'outline':
              return c + '-o';
            case 'twotone':
              return c + '-twotone';
            default:
              throw new TypeError('Unknown theme type: ' + e + ', name: ' + c);
          }

 

https://github.com/ant-design/ant-design/issues/19002

 

rollup 开发vue组件库及umd SDK 问题总结_第8张图片

 

注释掉message组件问题消失

image.png

rollup 开发vue组件库及umd SDK 问题总结_第9张图片

default.observable

image.png

 

https://github.com/59naga/babel-plugin-add-module-exports#readme

rollup 开发vue组件库及umd SDK 问题总结_第10张图片

 

Vue.observable小型状态管理

https://www.jianshu.com/p/b02d4693c40d

rollup 开发vue组件库及umd SDK 问题总结_第11张图片

rollup 开发vue组件库及umd SDK 问题总结_第12张图片

index.umd.js:1 Uncaught ReferenceError: require is not defined

rollup开发依赖包(npm library)实战

https://www.jianshu.com/p/2872fbaeb35b

 

本地开启https服务  ===>  https://codecat.blog.csdn.net/article/details/113634604

 

安装最新版rollup

http://www.voidcn.com/article/p-yjriqqee-bqu.html

image.png

index.umd.js:1 Uncaught TypeError: Cannot read property 'withScopeId' of undefined

关于Rollup编译vue的插件

npm i -D vue-template-compiler   vue-loader rollup-plugin-vue  babel-plugin-transform-vue-jsx

 

rollup 开发vue组件库及umd SDK 问题总结_第13张图片

在使用Babel去编译代码之前需要进行一些配置,该配置文件需要在src/目录下创建

touch src/.babelrc

内容:

{
    "presets": ["es2015-rollup"]
}


在经过上一步配置之后,还需要安装一下babel-preset-es2015-rollup

npm i -D babel-preset-es2015-rollup

上述步骤完成之后我们就可以在文件中使用ES2015特性了,如:

// src/main.js
import { version } from '../package.json';

const message = `current version is ${version}`;

export default () => console.log( message );

最后使用rollup -c打包得出以下结果:

// bundle.js
'use strict';

var version = '1.0.0';

var message = 'current version is ' + version;

var main = (function () {
    console.log( message );
});

module.exports = main;

上面 es-2015配置仅供参考,如下是实际使用配置

  presets: [
    [
      '@babel/preset-env',
      {
        debug: false, // debug,编译的时候 console
        useBuiltIns: 'usage', // 按需加载
        modules: false, // 模块使用 es modules ,不使用 commonJS 规范
        targets: {
          node: 'current', // 根据当前节点版本进行编译
        },
      },
    ],
  ],
 

https://blog.csdn.net/gccll/article/details/52785754

rollup 开发vue组件库及umd SDK 问题总结_第14张图片

 

rollup 开发vue组件库及umd SDK 问题总结_第15张图片

image.png

 

 Cannot read property 'extend' of undefined

 

npm install --save-dev rollup-plugin-clear

image.png

 

image.png

 

rollup 开发vue组件库及umd SDK 问题总结_第16张图片

在利用webpack的Vue项目中,在main.js中使用import Vue from 'vue' 导入的Vue的包,功能不完善,只是提供了runtime-only的方式,并没有提供像在普通网页中使用Vue那样的功能完善。

包的查找规则

(1)在项目根目录中查找有没有node_modules 的文件夹

(2)在node_modules 中,根据包名,找对应的vue文件夹

(3)在vue文件夹中,找一个叫做package.json的包配置文件

(4)在package.json文件中,查找一个main属性【main属性指定了这个包在被加载的时候  的入口文件】

因为在Vue包的package.json文件中main属性指定的入口文件【"main": "dist/vue.runtime.common.js",】,因此,在main.js中使用import Vue from 'vue' 导入的Vue构造函数,功能不完善。

解决办法:

(1)import Vue from '../node_modules/vue/dist/vue.js'

(2)在Vue包的package.json文件中main属性指定的入口文件修改为【"main": "dist/vue.js",】

(3)在项目的webpack.config.js中添加resolve属性

1.     resolve: {
2. alias: {
3. // 修改Vue倍导入时包的路径
4. "vue$" : "vue/dist/vue.js"
5.         }
6.

 

https://blog.csdn.net/sleepwalker_1992/article/details/82082400

vant 编译有问题 内部引用vue runtime

import aLiCallPlugin from "./aLiCall";
import tianRunCallPlugin from "./tianRunCall";
const version = "1.0.0";
const components = [aLiCallPlugin, tianRunCallPlugin];
const install = Vue => {
  const localVue = Vue;
  if (install.installed) return;
  components.forEach(component => {
    localVue.component(component.name, component);
  });
  localVue.prototype.$aLiCallPlugin = aLiCallPlugin;
  localVue.prototype.$tianRunCall = tianRunCallPlugin;
};

// 判断是否是直接引入文件
if (typeof window !== "undefined" && window.Vue) {
  install(window.Vue);
}

export { version, install, aLiCallPlugin, tianRunCallPlugin };

下部分Css模块配置暂未更新,可以做到支持

rollup 不支持 css scoped

const _withId = /*#__PURE__*/vue$1.withScopeId("data-v-88776a9e");

vant源码有报错

rollup 开发vue组件库及umd SDK 问题总结_第17张图片

 

组件中尽量用vue 运行时 即使用 vue.common.runtime.js 

rollup 开发vue组件库及umd SDK 问题总结_第18张图片

 

image.png

rollup 开发vue组件库及umd SDK 问题总结_第19张图片

 

https://stackoverflow.com/questions/53773128/vuejs-cannot-read-property-use-of-undefined-error

 

rollup 开发vue组件库及umd SDK 问题总结_第20张图片

出问题的地方在 babel的core-js,这个包里面使用有一个有一个判断优先级调整一下就好

解决参考文章 https://blog.csdn.net/qq_27667337/article/details/90634305

代码地址node_modules/core-js/client/core.js

原代码

  // Node.js
  if (isNode) {
    notify = function () {
      process.nextTick(flush);
    };
  // browsers with MutationObserver, except iOS Safari - https://github.com/zloirock/core-js/issues/339
  } else if (Observer && !(global.navigator && global.navigator.standalone)) {
    var toggle = true;
    var node = document.createTextNode('');
    new Observer(flush).observe(node, { characterData: true }); // eslint-disable-line no-new
    notify = function () {
      node.data = toggle = !toggle;
    };
  // environments with maybe non-completely correct, but existent Promise
  } else if (Promise && Promise.resolve) {
    // Promise.resolve without an argument throws an error in LG WebOS 2
    var promise = Promise.resolve(undefined);
    notify = function () {
      promise.then(flush);
    };
  // for other environments - macrotask based on:
  // - setImmediate
  // - MessageChannel
  // - window.postMessag
  // - onreadystatechange
  // - setTimeout
  } else {
    notify = function () {
      // strange IE + webpack dev server bug - use .call(global)
      macrotask.call(global, flush);
    };
  }

修改后的代码

if (isNode) {
    notify = function () {
      process.nextTick(flush);
    };
  // browsers with MutationObserver, except iOS Safari - https://github.com/zloirock/core-js/issues/339
  } else if (Promise && Promise.resolve) {
    // Promise.resolve without an argument throws an error in LG WebOS 2
    var promise = Promise.resolve(undefined);
    notify = function () {
      promise.then(flush);
    };
  // for other environments - macrotask based on:
  // - setImmediate
  // - MessageChannel
  // - window.postMessag
  // - onreadystatechange
  // - setTimeout
  } else if (Observer && !(global.navigator && global.navigator.standalone)) {
    var toggle = true;
    var node = document.createTextNode('');
    new Observer(flush).observe(node, { characterData: true }); // eslint-disable-line no-new
    notify = function () {
      node.data = toggle = !toggle;
    };
    // environments with maybe non-completely correct, but existent Promise
  } else {
    notify = function () {
      // strange IE + webpack dev server bug - use .call(global)
      macrotask.call(global, flush);
    };
  }

结论 :vant 中bug太多

 

安装必要的PostCSS插件。

在项目里,会使用到四个插件 - 两个是语法糖,一个用来在兼容旧浏览器的新CSS特性,一个用来压缩,减少生成的样式文件大小。

  • postcss-simple-vars — 可以使用Sass风格的变量(e.g. $myColor: #fff;color: $myColor;)而不是冗长的CSS语法(e.g. :root {--myColor: #fff}color: var(--myColor))。这样更简洁;我更喜欢较短的语法。
  • postcss-nested — 允许使用嵌套规则。实际上我不用它写嵌套规则;我用它简化BEM友好的选择器的写法并且划分我的区块,元素和修饰到单个CSS块。
  • postcss-cssnext — 这个插件集使得大多数现代CSS语法(通过最新的CSS标准)可用,编译后甚至可以在不支持新特性的旧浏览器中工作。
  • cssnano — 压缩,减小输出CSS文件大小。相当于JavaScript中对应的UglifyJS。

使用这个命令安装插件:

npm install --save-dev postcss-simple-vars postcss-nested postcss-cssnext cssnano

 

按需加载

image.png

 

rollup 开发vue组件库及umd SDK 问题总结_第21张图片

 

vue3 及依赖有问题,原rollup-plugin-vue 插件是yyx开发,最新版会将模板编译成vue3语法,出现大量undefined情况 ,初步估计插件不完整(据官方:vue3是兼容vue2语法的)

https://github.com/skyplaying/rollup-plugin-vue2 解决编译成vue3语法问题

结论:谨慎使用ui组件库 大多数组件库依赖webpack 如antd vant  其中也有一部分bug 建议手写组件

以上仅记录开发sdk中的问题,实战开发组件库和sdk构建细节待更新~~~

vuecli 开发组件库待更新~~~

wepack开发组件库及umd待更新~~~

构建原理梳理待更新~~~

你可能感兴趣的:(前端工程化,rollup,组件库)