一文带你搞定搭建自己的组件库Rollup

news/2024/7/10 1:20:17 标签: vue.js, 前端, css, vue

一文带你搞定搭建自己的组件库(rollup.js)

目前Vue和React都是采用rollup.js进行打包,我们在公司开发的时候也可以用rollup搭建一个自己的组件库放到你的项目中,简化项目的结构项目性能。

接下来我将带你使用rollup从0——1搭建一个在vue中使用的组件库

开发前准备

我的开发环境是

node -- 16.0.0
npm -- 7.10.0
//我的项目版本是
pinia -- ^2.1.7
vue   --  ^3.3.11
//我的项目是基于viet的vue3加Ts可视化项目
//我将使用rollup搭建一个组件库抽取公共的组件到rollup中后期发布到npm仓库中以达到简化项目结构的目的

这篇文章详细的记录了我搭建的过程以及解决报错的过程

开始

1.1搭建创建组件库

本节你将实现一个简单的rollup打包文件过程 以及使用打包后的代码

  • 在你的桌面上创建一个文件夹(我的文件夹名字是【Echarts-Screen-Libs】)

  • 拖动你的文件夹到vscode中打开命令行输入npm init 一路回车初始化npm

  • 修改你的package.json

    //this is my package.json
    {
      "name": "echarts-screen-libs",//change
      "version": "1.0.0",
      "description": "datav components library",//change
      "main": "index.js",
      "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1"
      },
      "author": "Joon",//change
      "license": "ISC" //这是开源协议(后期修改)
    }
    
  • 继续打开命令行安装rollup

    我的版本是"rollup": "^4.9.6"
    
  • 在项目中创建src文件夹 在src下创建index.js 里面写上一下内容

    console.log("你好 组件库!!")
    export default {}
    
  • 继续在你的项目中创建两个文件夹

    rollup.config.prod.js 线上环境调用
    rollup.config.dev.js  开发环境调用
    

    这里做个说明 我们在线上环境我们会进行压缩代码 而在开发环境不会去压缩代码

    所以这里我们创建两个配置文件 在不同环境中我们调用不同的config去执行rollup

  • 继续编写dev配置文件实现调用rollup打包

    // rollup.config.dev.js
    const path = require("path")
    const inputPath = path.resolve(__dirname, "./src/index.js")
    const outputPath = path.resolve(__dirname, "./dist/screen.datav.js")
    module.exports = {
        input: inputPath,
        output: {
            file: outputPath,
            format: "umd"//最后解释
        }
    }
    
  • 继续修改package.json

      "scripts": {
          // -wc
        "dev": "rollup -wc rollup.config.dev.js"
      },
    

    通过 npm run dev去调用 rollup实现打包

    rollup -wc rollup.config.dev.js是一个rollup命令行工具的参数。

    • -w--watch:启用监视模式,当代码发生变化时自动重新构建。
    • -c--config:指定配置文件的路径。
    • rollup.config.dev.js:指定要使用的配置文件的文件名。

    因此,该命令会使用名为rollup.config.dev.js的配置文件,并在其基础上启用监视模式。这意味着如果配置文件或输入文件中的代码发生更改,则rollup将自动重新构建打包文件。

  • 当你执行完 npm run dev 应该不会有报错 可以看一下dist文件夹下已经打包出来了文件

  • 到这里你就完成了一个简单的打包

  • 我们在项目中创建一个文件夹 叫example 在该文件夹下创建一个index.html测试一下我们的打包代码

    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <script src="../dist/screen.datav.js">
    
        </script>
    </head>
    
    <body>
        <h1>
            this is test file
        </h1>
    
    </body>
    
    </html>
    

    运行该文件我们可以看见该js脚本运行没有问题

  • 这里我们解释一下在dev配置文件中 format: “umd” 是什么意思

    ​ format 的选项有什么呢:

    • umd

      在上述的rollup.config.dev.js配置文件中,format: "umd"用于指定rollup的输出格式。

      UMD(Universal Module Definition)是一种通用的模块系统,它兼容多个环境,包括浏览器、Node.js和AMD(异步模块定义)。通过将代码包装在UMD的模块定义中,可以在不同的环境中使用相同的代码。

      format设置为"umd"会生成一个UMD模块,它可以在浏览器和Node.js环境中都可以使用。UMD模块既可以通过<script>标签直接引入,也可以使用CommonJS或AMD模块加载器进行导入。

      此外,UMD模块还允许您通过在全局命名空间中暴露一个全局变量来直接访问模块的导出内容。例如,如果在配置文件中指定了name选项,那么format: "umd"将在全局命名空间中定义一个具有该名称的变量,您可以使用该变量访问模块的导出内容。

      总而言之,format: "umd"在Rollup的配置中表示输出格式为UMD模块,这意味着您可以在不同的环境中使用该模块。

      如果你写了umd 他会以js函数形式导出。

    • cjs

      format: "cjs"表示在Rollup的配置中设置输出格式为CommonJS模块。

      CommonJS是一种用于JavaScript模块化的规范,主要用于Node.js环境。CommonJS模块化规范允许将代码分割到模块中,并通过require函数导入和导出模块。

      format选项设置为"cjs",Rollup将生成符合CommonJS模块规范的输出文件。这意味着您可以在Node.js环境中使用生成的文件,通过require语句导入模块,获取导出的内容。通常,CommonJS模块也可以在支持CommonJS规范的前端构建工具中使用。

      总结一下,format: "cjs"指示Rollup生成符合CommonJS模块规范的输出文件,使您可以在Node.js环境中使用该文件。如果你写了cjs 他会以module.exports进行导出模块,这种形式在浏览器是运行不了的 这也是为什么许多CommonJS需要通过webpack或者rollup打包成umd模式在浏览器使用

    • es

      format: "es"是Rollup配置选项中的一种输出格式,意味着输出的代码将符合ES模块规范。

      ES模块是一种用于JavaScript模块化的规范,它在现代浏览器、Node.js环境以及许多支持JavaScript的应用程序中得到了支持。它使用 importexport 关键字来定义和导入/导出模块。

      如果在使用format: "es"进行Rollup构建时,将会输出符合ES模块规范的代码,这意味着它可以直接在现代浏览器和支持ES模块规范的环境中使用。可以通过import语句导入模块的内容,与其他模块进行交互。

      需要注意的是,ES模块通常不能在Node.js环境中直接使用,因为Node.js目前仅支持部分的ES模块规范,因此需要使用专门的工具或插件进行转换和处理。

      综上所述,format: "es"意味着Rollup将以符合ES模块规范的格式输出代码,让它可以在现代浏览器和支持ES模块的环境中直接使用。

      如果你写了es 他会以 export default xxx j进行导出 这种形式的代码浏览器也是不太支持 也有解决方法 大家可以百度一下浏览器怎么运行 es模块

  • 总结 我们建议你使用umd模式去打包你的组件库

    当然你也可以在output中配置多个输出 可以输出多种形式的模块 比如cjs es等等

1.2配置rollup插件(配置dev)

在1.1中我们完成了一个简单的输出 讲解了一个简单的rollup配置文件,如果你想配置rollup实现组件库我们还需要配置一些插件

1.2.1配置bable-node

我们在开发组件库的时候难免会遇到要编写es6 的情况我们先解决这个问题

这里我们执行npm命令去安装sam老师的库

npm i sam-test-data

我们尝试用rollup去打包我们写的es语法

我们改写一下index.js

console.log("你好 组件库!!")
// es6语法
import data from 'sam-test-data'
console.log(data.random(), data.a, data.b)
export default {}

我们尝试去用node 运行一下

C:\Users\Joon\Desktop\Echarts-Screen-Libs\src\index.js:3
import data from 'sam-test-data'
^^^^^^
SyntaxError: Cannot use import statement outside a module
    at Object.compileFunction (node:vm:355:18)
    at wrapSafe (node:internal/modules/cjs/loader:1038:15)
    at Module._compile (node:internal/modules/cjs/loader:1072:27)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1137:10)
    at Module.load (node:internal/modules/cjs/loader:988:32)
    at Function.Module._load (node:internal/modules/cjs/loader:828:14)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:76:12) 
    at node:internal/main/run_main_module:17:47

可以看见我们不能运行改代码

配置babel/node

  • 安装npm install --save-dev @babel/node

安装完成后 你可以尝试运行一下 babel-node ./src/index.js

无疑报错

$ babel-node src/index.js
(node:15944) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
(Use `node --trace-warnings ...` to show where the warning was created)
C:\Users\Joon\Desktop\Echarts-Screen-Libs\src\index.js:3
import data from 'sam-test-data';
^^^^^^
SyntaxError: Cannot use import statement outside a module
    at Object.compileFunction (node:vm:355:18)
    at wrapSafe (node:internal/modules/cjs/loader:1038:15)
    at Module._compile (node:internal/modules/cjs/loader:1072:27)
    at Module._compile (C:\Users\Joon\AppData\Roaming\npm\node_modules\@babel\node\node_modules\pirates\lib\index.js:117:24)
    at Module._extensions..js (node:internal/modules/cjs/loader:1137:10)
    at Object.newLoader [as .js] (C:\Users\Joon\AppData\Roaming\npm\node_modules\@babel\node\node_modules\pirates\lib\index.js:121:7)
    at Module.load (node:internal/modules/cjs/loader:988:32)
    at Function.Module._load (node:internal/modules/cjs/loader:828:14)
    at Function.runMain (node:internal/modules/run_main:76:12)
    at Object.<anonymous> (C:\Users\Joon\AppData\Roaming\npm\node_modules\@babel\node\src\_babel-node.ts:222:12)

Why 我们还需要安装一个插件叫 @babel/core 继续执行 babel-node .\src\index.js

你会发现还是有报错

我们还需要进行配置

babel的用途是将es6转换为es5的语法

我们需要在项目目录下创建 .babelrc文件去配置一下babel

怎么配置会查的小朋友都去官网看 不会查的直接复制我的

{
    "presets": [
        [
            "@babel/preset-env"
        ]
    ]
}

再次运行babel-node .\src\index.js 还是有报错

注意看: Error: Cannot find module ‘@babel/preset-env’

$ babel-node src/index.js
C:\Users\Joon\AppData\Roaming\npm\node_modules\@babel\core\lib\gensync-utils\functional.js:53
    if (result.ok) return result.value;else throw result.value;
                       
Error: Cannot find module '@babel/preset-env'

再次安装 npm i -D @babel/preset-env

再次运行babel-node .\src\index.js

还是有报错

你好 组件库!!
C:\Users\Joon\Desktop\Echarts-Screen-Libs\src\index.js:12
console.log(_samTestData.default.random(), _samTestData.default.a, _samTestData.default.b);
                                 ^

TypeError: Cannot read property 'random' of undefined
    at Object.<anonymous> (C:\Users\Joon\Desktop\Echarts-Screen-Libs\src\/index.js:4:18)
    at Module._compile (node:internal/modules/cjs/loader:1108:14)
    at Module._compile (C:\Users\Joon\AppData\Roaming\npm\node_modules\@babel\node\node_modules\pirates\lib\index.js:117:24)
    at Module._extensions..js (node:internal/modules/cjs/loader:1137:10)
    at Object.newLoader [as .js] (C:\Users\Joon\AppData\Roaming\npm\node_modules\@babel\node\node_modules\pirates\lib\index.js:121:7)
    at Module.load (node:internal/modules/cjs/loader:988:32)
    at Function.Module._load (node:internal/modules/cjs/loader:828:14)
    at Function.runMain (node:internal/modules/run_main:76:12)
    at Object.<anonymous> (C:\Users\Joon\AppData\Roaming\npm\node_modules\@babel\node\src\_babel-node.ts:222:12)

我们仔细看 问题不大了 你好 组件库!!以及出来了 这里主要的问题就是

他无法识别

import data from ‘sam-test-data’

他无法识别data 所以他会报错

我们改一下语法 import * as data from ‘sam-test-data’

再次运行

$ babel-node src/index.js
你好 组件库!!
0 9 78

终于成功了!

我们再次测试一下修改一下index.js文件

console.log("你好 组件库!!")
// es6语法
// import * as data from 'sam-test-data'
import { random, a, b } from 'sam-test-data'
console.log(random(), a, b)
export default {}

再次运行babel-node .\src\index.js

发现可以运行那么我们的es6语法转换为es5语法就解决了

1.2.2配置node-resolve

先说结论我们在没有配置node-resolve插件的时候 我们将我们打包后的screen.datav.es.js或者screen.datav.js这两个文件单独拿出去运行是不能运行的他会提示你他找不到data模块就是我们下载的sam-test-data中暴露的代码

比如说你现在把你打包的代码拷贝到桌面用的命令行去运行一下你会发现他跑不动

Joon@DESKTOP-IE2H5KG MINGW64 ~/Desktop
$ node screen.datav.js
node:internal/modules/cjs/loader:943
  throw err;
  ^
Error: Cannot find module 'sam-test-data'

为了我们能将打包出来的文件可以单独运行 我们就需要使用到@rollup/plugin-node-resolve这个库

  • 安装插件npm i @rollup/plugin-node-resolve

  • 在dev.config中配置plugins

    const path = require("path")
    const inputPath = path.resolve(__dirname, "./src/index.js")
    const outputPathUmd = path.resolve(__dirname, "./dist/screen.datav.js")
    const outputPathejs = path.resolve(__dirname, "./dist/screen.datav.es.js")
    const resolve = require("@rollup/plugin-node-resolve")//看这里
    module.exports = {
        input: inputPath,
        output: [
            {
                file: outputPathUmd,
                format: "umd",
                name: "screenDatav"
            },
            {
                file: outputPathejs,
                format: "es",
                name: "screenDatav"
            },
    
        ],
        plugins: [
            resolve()//看这里
        ]
    }
    
  • 在项目中再次打包并且拷贝我们打包后的文件到桌面尝试运行

    $ node screen.datav.js
    你好 组件库!!
    0 1 89
    
  • 成功单独运行

1.2.3触发tree-shaking

tree-shaking(摇树) 把树上的枯树叶摇掉,也就是简化我们的打包体积相当于elementui中的按需引入

下面用一个例子讲清楚tree-shaking的概念

  • 在你的项目下的src下创建plugin.js文件

    const a = 1;
    const b = 2;
    function sayHello() {
        console.log("你好啊")
    }
    export default {
        a,
        b,
        sayHello
    }
    
  • index.js

    // 演示tree-shaking
    import { a, b, sayHello } from './plugin'
    console.log(a)
    console.log(b)
    console.log(sayHello
    
    export default sayHello
    
  • 执行 babel-node src/index.js

    $ babel-node src/index.js
    undefined
    undefined
    undefined
    

    三个undefined why

    解析:

    如果我们在index.js下面通过 import * as data from './plugin'

    其实我们引入的a b sayHello 都不是最终的引入 他实际上是放在 {default:{a:1,b:2,sayhello:[function:sayhello]}}中

    所以我们调用也需要这样调用

    //index.js
    // 演示tree-shaking
    import * as data from './plugin'
    
    console.log(data.default.sayHello)
    
    export default data.default.sayHello
    
  • 运行 没问题了

    Joon@DESKTOP-IE2H5KG MINGW64 ~/Desktop/Echarts-Screen-Libs
    $ babel-node src/index.js
    1
    2
    [Function: sayHello]
    

    现在开始演示tree-shaking

    在你的package.json中在配置一个命令

    "scripts": {
        "dev": "rollup -wc rollup.config.dev.js",
        "build": "rollup -c rollup.config.dev.js" //add
      },
    

    现在你去执行npm run build 你去看看打包后的代码

    (function (global, factory) {
        typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
        typeof define === 'function' && define.amd ? define(factory) :
        (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.screenDatav = factory());
    })(this, (function () { 'use strict';
    
        const a = 1;
        const b = 2;
        function sayHello() {
            console.log("你好啊");
        }
        var plugin = {
            a,
            b,
            sayHello
        };
    
        // 演示tree-shaking
    
        console.log(plugin.sayHello);
    
        var index = plugin.sayHello;
    
        return index;
    
    }));
    

    我们可以发现a和b我们没有使用但是他还是打包了 这就很难受 我不用你还给我

    我们的tree-shaking就是解决这个问题的

    为什么会有这个问题因为你用了import * as data from ‘./plugin’

    因为你导入了*导入的是所有的内容所以他会打包

    这里插一嘴

    vue2中他就是利用了类似于export default {a, b,sayHello}这种导出方式 他导出的是所有所以就导致了vue2无法实现tree-shking机制而vue3可以!

    我们怎么去出发tree-shking呢

    我们改写一下plugin.js

    export const a = 1;
    export const b = 2;
    export function sayHello() {
        console.log("你好啊")
    }
    

    再次改写index.js

    // 演示tree-shaking
    import { sayHello, a, b } from './plugin'
    
    console.log(data.default.sayHello)
    
    export default data.default.sayHello
    

    再次打包看看你的打包后的代码

    (function (global, factory) {
        typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
        typeof define === 'function' && define.amd ? define(factory) :
        (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.screenDatav = factory());
    })(this, (function () { 'use strict';
    
        function sayHello() {
            console.log("你好啊");
        }
    
        // 演示tree-shaking
    
        console.log(sayHello);
    
        return sayHello;
    
    }));
    
    

    a和b没了 成功触发

1.2.4配置external属性

有些场景下,虽然我们使用了resolve插件,但我们仍然某些库保持外部引用状态,这时我们就需要使用external属性,告诉rollup.js哪些是外部的类库

配置他的目的就是不要把vue的代码或者其他的外部库全部打包到我们的库中

const path = require("path")
const inputPath = path.resolve(__dirname, "./src/index.js")
const outputPathUmd = path.resolve(__dirname, "./dist/screen.datav.js")
const outputPathejs = path.resolve(__dirname, "./dist/screen.datav.es.js")
const resolve = require("@rollup/plugin-node-resolve")
module.exports = {
    input: inputPath,
    output: [
        {
            file: outputPathUmd,
            format: "umd",
            name: "screenDatav"
        },
        {
            file: outputPathejs,
            format: "es",
            name: "screenDatav"
        },

    ],
    plugins: [
        resolve()
    ],
    external: [
        "vue"
    ]
}

不多赘述

1.2.5配置commonjs

commonjs我们刚刚演示了 他是通过require引入一个模块 通过module.exports导出一个模块,rollup.js默认不支持CommonJS模块,他默认就是做es6打包的。

演示一下我们为什么需要配置CommonJS模块

在你的项目src下创建c.js

//c.js
const a = 1
module.exports = a	
//index.js
import data from './c'
console.log(data)
export default data

通过 babel-node不难发现我们可以运行

我们尝试打包 可以发现报错了

[!] RollupError: "default" is not exported by "src/c.js", imported by "src/index.js".

我的的commonjs输出的时候是没有default这个属性的要解决这个问题我们需要去配置commonjs插件

  • npm i -D rollup-plugin-commonjs

  • 修改配置文件

    const path = require("path")
    const inputPath = path.resolve(__dirname, "./src/index.js")
    const outputPathUmd = path.resolve(__dirname, "./dist/screen.datav.js")
    const outputPathejs = path.resolve(__dirname, "./dist/screen.datav.es.js")
    const resolve = require("@rollup/plugin-node-resolve")
    const commonjs = require("rollup-plugin-commonjs")//add
    module.exports = {
        input: inputPath,
        output: [
            {
                file: outputPathUmd,
                format: "umd",
                name: "screenDatav"
            },
            {
                file: outputPathejs,
                format: "es",
                name: "screenDatav"
            },
    
        ],
        plugins: [
            resolve(),
            commonjs()//add
        ],
        external: [
            "vue"
        ]
    }
    
  • 再次执行打包就没有问题了

  • 如何触发three-shking呢

    //我们在导出的时候我们这样导出就行
    //index.js
    import { a, b } from './c'
    console.log(a)
    export default a
    //c.js
    exports.a = 1
    exports.b = 1
    
  • 再次打包看看打包结果没问题触发了tree-shiking

  • 总结一下

    我们在esmodule中触发tree-shking

    export const a=1;

    我们在commonjs中触发tree-shking

    exports.a = 1

    引入都是通过结构进行引入

    import { a, b } from ‘./c’

1.2.6配置bable模块

安装:npm install @rollup/plugin-babel --save-dev

比如我们在index.js中写了es6语法我们需要在打包的时候把es6语法转换为es5

引入插件 调用插件

const path = require("path")
const inputPath = path.resolve(__dirname, "./src/index.js")
const outputPathUmd = path.resolve(__dirname, "./dist/screen.datav.js")
const outputPathejs = path.resolve(__dirname, "./dist/screen.datav.es.js")
const resolve = require("@rollup/plugin-node-resolve")
const commonjs = require("rollup-plugin-commonjs")
const babel = require("@rollup/plugin-babel")//add
module.exports = {
    input: inputPath,
    output: [
        {
            file: outputPathUmd,
            format: "umd",
            name: "screenDatav"
        },
        {
            file: outputPathejs,
            format: "es",
            name: "screenDatav"
        },

    ],
    plugins: [
        resolve(),
        commonjs(),
        babel({
            // 表示那些不需要转换
            exclude:"node_modules/**"
        })//add
    ],
    external: [
        "vue"
    ]
}
1.2.7配置json模块

为什么要配置?演示给你看

首先我们修改index.js

import pack from '../package.json'
var mainEs = (base) => {
    return random(base)
};
export default mainEs;

然后我们执行打包

[!] RollupError: Expected ';', '}' or <eof> (Note that you need @rollup/plugin-json to import JSON files)

因为 json文件不支持模块化构建

1.3配置rollup插件(配置prod)

我们在上线项目的时候我们事实上需要对代码进行压缩这里我们使用@rollup/plugin-terser插件进行压缩代码

首先把我们刚刚配置好的env配置文件全部复制到prod文件下

安装@rollup/plugin-terser插件

npm install @rollup/plugin-terser --save-dev
//rollup.config.prod.js
const path = require("path")
const inputPath = path.resolve(__dirname, "./src/index.js")
const outputPathUmd = path.resolve(__dirname, "./dist/screen.datav.js")
const outputPathejs = path.resolve(__dirname, "./dist/screen.datav.es.js")
const resolve = require("@rollup/plugin-node-resolve")
const commonjs = require("rollup-plugin-commonjs")
const babel = require("@rollup/plugin-babel");
const json = require("@rollup/plugin-json");
import terser from "@rollup/plugin-terser"
module.exports = {
    input: inputPath,
    output: [
        {
            file: outputPathUmd,
            format: "umd",
            name: "screenDatav"
        },
        {
            file: outputPathejs,
            format: "es",
            name: "screenDatav"
        },

    ],
    plugins: [
        resolve(),
        commonjs(),
        babel({
            exclude: "node_modules/**",
        }),
        json(),
        terser()
    ],
    external: [
        "vue"
    ]
}

紧接着我们在package.json中创建命令

  "scripts": {
    "dev": "rollup -wc rollup.config.dev.js",
    "build": "rollup -c rollup.config.dev.js",
    "build:prod":"rollup -c rollup.config.prod.js"//add
  },

执行npm run build:prod 再次看打包后的代码 压缩了没问题!

vue_858">1.4配置解析vue文件

截至目前 你完成了对各种js的解析

解析来我们就要进入最重要的环节了配置解析vue文件

首先你去创建一个test.vue文件

vue"><template>
    <div class="Wrapper">
        <h1>wanhgfeng</h1>
    </div>
</template>

<script setup lang="ts"></script>
<script>
export default {
    name: 'TestComponent'  // 添加name属性
}
</script>
<style scoped lang="scss">
h1 {
    color: red;
}
</style>
//index.js
import test from './Test.vue'
export default function (vue) {
    vue.component(test.name, test)
}

执行打包

[!] RollupError: Expression expected (Note that you need plugins to import files that are 
not JavaScript)

报错了为啥 你没装插件

继续安装以及调用函数

npm i -D rollup-plugin-vue

const vue = require(“rollup-plugin-vue”)

vue()

注意:你的vue函数必须放在plugins中的第一位 所有的函数靠后vue先调用

别忘了两个环境dev和prod都要加

继续打包—还是报错

[!] RollupError: Identifier cannot follow number (Note that you need plugins to import files that are not JavaScript)
src/Test.vue?vue&type=style&index=0&id=07bdddea&scoped=true&lang.scss (2:12)
1:
2: h1 {
        ^
3:     color: red;
4: }

因为你的scss没有解析插件

老套路

npm i rollup-plugin-postcss

const postcss = require(“rollup-plugin-postcss”)

postcss()

再次打包—还是报错

[!] (plugin postcss) Error: You need to install one of the following packages: "sass", "node-sass" in order to process SASS files

why – 去安装sass或者node -sass

npm i -D scss

好的我帮你们踩坑了这里即使你安装了scss还是没用

继续安装就可以打包了(真不容易)

npm install -D sass-loader@^10 sass

到此为止 我们实现了vue的解析

还有一个报错

(!) Missing global variable name

我们在output中添加一个

global 就行

  output: [
        {
            file: outputPathUmd,
            format: "umd",
            name: "screenDatav",
            globals: {
                vue: "vue"
            }
        },
        {
            file: outputPathejs,
            format: "es",
            name: "screenDatav",
            globals: {
                vue: "vue"
            }
        },

    ],

2.1测试组件库

改动你的index.html

<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://unpkg.com/vue@3.3.11/dist/vue.global.js"></script>  <!-- 引入你的vuecdn地址  -->   <!-- 注意你的vue版本 -->
    <script src="../dist/screen.datav.js"></script>  <!-- 引入你的库 -->
</head>

<body>
    <div id="app">
        {{message}}
        <test-component></test-component>
    </div>
    <script>
        Vue.createApp({
            setup() {
                var message = "wanfeng"
                return {
                    message
                }
            }
        }).use(screenDatav).mount("#app")
          <!-- 尤其注意这里 你需要use 模块的名称 其实就是你的配置问文件的name screenDatav -->
        <!--这个name其实就会变成一个全局的对象所以你需要挂载他-->
    </script>

</body>

</html>

然后还有一个问题 找到你打包的

screen.datav.js 找到这个一行

    (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.screenDatav = factory(global.vue));
    //注意看global.vue 他是小写的 我们使用的是大写的Vue创建的app 所以你需要手动修改一下 
global.Vue

这里有的同学就觉得不太行老子每次执行一下打包都要改多烦

其实不用担心我们后期使用模块化开发他不会执行到这里

他会判断

exports是否存在

function是否存在 不会走到这里

 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('vue')) :
 typeof define === 'function' && define.amd ? define(['vue'], factory) :

vue_1052">2.2嵌入vue项目中

做这一步你需要有个vue3项目自己去创建

连接之前我们需要修改package.json中的 “main”: “./dist/screen.datav.js”,

这个main是默认引入指向的文件 我们指向我们打包后的js 上线后我们把他指向.min.js

然后我们在package.json中添加

file属性 改属性是指我们在推到npm仓库会包含那些文件

 "files": [
    "dist",
    "src"
  ],

最后执行 npm link

不知道我的笔记本愁什么风 执行后没有输出 我就只能苦苦找link包

我的地址是

C:\Users\Joon\AppData\Roaming\npm\node_modules\echarts-screen-libs

最后的echarts-screen-libs是你的package.json中的name名字

按照这个地址你去找指定能找到,当然希望你有输出

然后去你的vue3项目中 的package.json手动添加一个依赖后期你发布了组件库就好多了

  "dependencies": {
    "pinia": "^2.1.7",
    "vue": "^3.3.11",
    "echarts-screen-libs":"1.0.0"
  },

然后打开你vue3项目的命令行执行

npm link echarts-screen-libs

最后去你的node_modules中查看一下有没有加入

在这里插入图片描述

然后在main.ts中添加使用

import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
// 引入pinia并实例化
import { createPinia } from 'pinia'
import datav from 'echarts-screen-libs'//add
const pinia = createPinia()
createApp(App).use(datav).use(pinia).mount('#app')//add

可能你的项目还是会报错 因为你的lib没有安装eslint我这里没有使用eslint所以我不用报错

你去添加一下就行了

最后我建议你不要用vite

我打包组件的时候 测试了一下环境

webpack + ts +vue 通过

webpack + js +vue 通过

vite +ts +vue 报错

vite +js +vue 报错

https://juejin.cn/post/6984896065791229989
https://github.com/vuejs/vue-cli/issues/7423

],


最后执行 npm link

不知道我的笔记本愁什么风 执行后没有输出 我就只能苦苦找link包

我的地址是

C:\Users\Joon\AppData\Roaming\npm\node_modules\echarts-screen-libs


最后的echarts-screen-libs是你的package.json中的name名字

按照这个地址你去找指定能找到,当然希望你有输出

然后去你的vue3项目中 的package.json手动添加一个依赖后期你发布了组件库就好多了

“dependencies”: {
“pinia”: “^2.1.7”,
vue”: “^3.3.11”,
“echarts-screen-libs”:“1.0.0”
},


然后打开你vue3项目的命令行执行

npm link echarts-screen-libs

最后去你的node_modules中查看一下有没有加入

[外链图片转存中...(img-XqOPxC83-1707312769836)]

然后在main.ts中添加使用

```ts
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
// 引入pinia并实例化
import { createPinia } from 'pinia'
import datav from 'echarts-screen-libs'//add
const pinia = createPinia()
createApp(App).use(datav).use(pinia).mount('#app')//add

可能你的项目还是会报错 因为你的lib没有安装eslint我这里没有使用eslint所以我不用报错

你去添加一下就行了

最后我建议你不要用vite

我打包组件的时候 测试了一下环境

webpack + ts +vue 通过

webpack + js +vue 通过

vite +ts +vue 报错

vite +js +vue 报错

https://juejin.cn/post/6984896065791229989
https://github.com/vuejs/vue-cli/issues/7423

这里我看了两篇文章还是没解决 各位大佬们自己看看吧


http://www.niftyadmin.cn/n/5369018.html

相关文章

deepin20.9安装及配置

安装deepin20.9很简单&#xff0c;刻录u盘 安装 一路next apt install nginx global vim-nox debian11 使用apt安装php, 使php多版本共存_debain11 php5-CSDN博客 vim LeaderF安装问题 - 知乎 debian10安装vue环境, 包括安装node.js-CSDN博客 debian安装vue3 nodejs20-CSD…

Redis——面试+思想+应用

文章目录 简介Redis基本介绍&#xff1a;性能&#xff1a;持久性和复制&#xff1a;补充——重点&#xff1a;Redis额外支持的操作&#xff1a; 使用场景&#xff1a;与Java的集成&#xff1a;Redis集群Redis Sentinel优点&#xff1a;缺点&#xff1a;适用场景&#xff1a; Re…

javaSSMmsql疫情时期人员流调平台69124-计算机毕业设计项目选题推荐(附源码)

目 录 摘要 1 绪论 1.1研究意义 1.2开发现状 1.3系统开发技术的特色 1.4 ssm框架介绍 1.5论文结构与章节安排 2 疫情时期人员流调平台系统分析 2.1 可行性分析 2.2 系统流程分析 2.2.1数据增加流程 2.2.2数据修改流程 2.2.3数据删除流程 2.3 系统功能分析 2.3.1…

时光峰峦文物璀璨,预防性保护筑安全

在璀璨的历史长河中&#xff0c;珍贵文物如同时间的印记&#xff0c;承载着过往的辉煌。《人文山水时光峰峦——多彩贵州历史文化展》便是这样一场文化的盛宴&#xff0c;汇聚了众多首次露面的宝藏。然而&#xff0c;文物的保存对环境要求极为苛刻&#xff0c;温湿度波动都可能…

从零学算法162

162.峰值元素是指其值严格大于左右相邻值的元素。 给你一个整数数组 nums&#xff0c;找到峰值元素并返回其索引。数组可能包含多个峰值&#xff0c;在这种情况下&#xff0c;返回 任何一个峰值 所在位置即可。 你可以假设 nums[-1] nums[n] -∞ 。 你必须实现时间复杂度为 O…

1795. 每个产品在不同商店的价格

说在前面 &#x1f388;不知道大家对于算法的学习是一个怎样的心态呢&#xff1f;为了面试还是因为兴趣&#xff1f;不管是出于什么原因&#xff0c;算法学习需要持续保持。 题目描述 表&#xff1a;Products ---------------------- | Column Name | Type | ------------…

Nginx中logs的nginx.pid文件引发的问题

Nginx中logs的nginx.pid文件引发的问题 Q1&#xff1a;nginx: [error] CreateFile() "D:\software\nginx-1.22.1/logs/nginx.pid" failed (2: The system cannot find the file specified)Q2&#xff1a;nginx: [error] invalid PID number "" in "D:…

记录 | .ui转.py

方法一&#xff1a;直接使用命令行 python -m PyQt5.uic.pyuic xx.ui -o xx.py 方法二&#xff1a;直接使用命令 先进到 C:\python\pkgs\pyqt-5.9.2-py37h6538335_2\Library\bin 里面 然后执行 pyuic5 在anaconda的pkg里面 pyuic5 pyqt5_01.ui -o pyqt5_01_ui.py 方法三…