企业内部私有组件库搭建

1,311 阅读3分钟

企业内部私有组件库搭建

因为在企业中的项目或组件库等技术有可能需要闭源的,所以不可以直接将组件库或代码等相关资料直接发布到Npm或Github上

解决方法

通过sinopia或verdaccio在内部服务器上搭建npm环境,因为sinopia已经有两三年没维护了,后来有开发者Fork出来进行维护,就是verdaccio,因此我们选用的是verdaccio

安装:

npm install -g verdaccio

运行:

verdaccio

或者使用pm2进行线程守护

pm2 start verdaccio

当我们安装并运行verdaccio后,就可以在localhost:4873进行访问了

使用nrm管理npm源

安装:

npm i -g nrm

将npm源更改为verdaccio

nrm add lw http://localhost:4873

查看nrm配置

nrm ls

切换nrm默认源

nrm use lw

删除nrm源

nrm del lw

组件库的搭建

当我们安装好verdaccio和nrm,私有npm就算是搭建好了,接下来就需要来搭建组件库并发布上去

1.搭建环境

# 安装vue-cli
npm i -g vue-cli
# 初始化vue-cli项目
vue init webpack project
# 切换到项目中
cd project
# 安装依赖
npm i
# 运行
npm run dev

2.搭建目录结构

├─ examples //原来src目录,改为文档
├─ packages //用于存放组件

我们修改完目录名之后也需要再修改下webpack的配置
首先先打开build/webpack.base.conf.js,修改为我们对应的目录

{
    test: /\.js$/,
    loader: 'babel-loader',
    include: [resolve('examples'), resolve('test'), resolve('packages')]
}

3.搭建编写文档环境 对于文档的编写,首当其选就是markdown了。
我们可以使用vue-markdown-loader 还是修改build/webpack.base.conf.js

{
    test: /\.md$/,
    loader: 'vue-markdown-loader',
    options: vueMarkdown
}

现在我们的环境就算搭建好了,可以开始写文档了
在examples/docs新建test.md,同时也需要配置下路由

{
    path:"/test",
    name:"test",
    component:resolve=>require.ensure([],()=>resolve(require('../docs/test.md')))
}

现在可以看到md文件以及成功编译了,但是我们还需要对组件的源代码进行展示
在vue-markdown-loader支持为我们的markdown文件自定义标识,然后进行处理
我们需要处理下vue-markdown-loader的配置

const vueMarkdown = {
  preprocess: (MarkdownIt, source) => {
    MarkdownIt.renderer.rules.table_open = function () {
      return '<table class="table">'
    }
    MarkdownIt.renderer.rules.fence = utils.wrapCustomClass(MarkdownIt.renderer.rules.fence)
    return source
  },
  use: [
    [MarkdownItContainer, 'demo', {
      // 用于校验包含demo的代码块
      validate: params => params.trim().match(/^demo\s*(.*)$/),
      render: function(tokens, idx) {
         
        var m = tokens[idx].info.trim().match(/^demo\s*(.*)$/);
 
        if (tokens[idx].nesting === 1) {
          var desc = tokens[idx + 2].content;
          // 编译成html
          const html = utils.convertHtml(striptags(tokens[idx + 1].content, 'script'))
          // 移除描述,防止被添加到代码块
          tokens[idx + 2].children = [];
 
          return `<demo-block>
                        <div slot="desc">${html}</div>
                        <div slot="highlight">`;
        }
        return '</div></demo-block>\n';
      }
    }]
  ]
}

将vue模板编译成html用于显示,demo-block就是我们定义好的组件,以及对代码高亮的处理

<template>
  <div class="docs-demo-wrapper">
      <div :style="{maxHeight: isExpand ? '700px' : '0'}" class="demo-container">
        <div span="14">
          <div class="docs-demo docs-demo--expand">
            <div class="highlight-wrapper">
              <slot name="highlight"></slot>
            </div>
          </div>
        </div>
      </div>
      <span class="docs-trans docs-demo__triangle" @click="toggle">
        {{isExpand ? '隐藏代码' : '显示代码'}}
      </span>
  </div>
</template>

在md文件中编写vue组件的正确方式

<div class="demo-block">
    <y-button>默认按钮</y-button>    
    <y-button type="primary">成功按钮</y-button>    
</div>
::: demo  ```html
<y-button>默认按钮</y-button>    
<y-button type="primary">成功按钮</y-button>
```  :::

处理组件项目引入问题

import Button from './button/index.js';
const components = [
  Button,
];
//处理全局引入
const install = function(Vue) {
  if (install.installed) return;
  components.map(component => Vue.component(component.name, component));
};
if (typeof window !== 'undefined' && window.Vue) {
  install(window.Vue);
}
//按需引入
export default {
  install,
  Button,
};

因为在SPA项目中,每个vue组件的样式有可能使用scoped,那么样式就无法从组件中抽离出来,也无法直接修改主题色。需要单独自行编译一套样式。对于css的命名使用了BEM规范 postcss允许配置BEM规范之间的连接符和缩写。

{
  "browsers": ["ie > 8", "last 2 versions"],
  "features": {
    "bem": {
      "shortcuts": {
        "component": "b",
        "modifier": "m",
        "descendent": "e"
      },
      "separators": {
        "descendent": "__",
        "modifier": "--"
      }
    }
  }
}

然后可以通过gulp打包编译出样式代码

gulp.task('compile', function() {
  return gulp.src('./src/*.css')
    .pipe(postcss([salad]))
    .pipe(cssmin())
    .pipe(gulp.dest('./lib'));
});

然后再我们需要的项目main.js引入

import YSUI from '../packages/index'
import '../pageages/theme-default/lib/index.css'
Vue.use(YSUI);