preface

Currently working on a vue component library (there are stories about that too…) After building the wheel, you need to write the component document, choose Vuepress, in the document need to demonstrate the code, naturally need to introduce the component library, after introducing the component library to write the document normal use no problem, but in the build time trouble…

The problem

  • Problem a

    ReferenceError: document is not defined

    The reason for this problem is that when I wrote the vue component, I introduced a style file in the.vue file, which looks like this:

    <style lang="less"> @import '.. /style/content.less'; </style>Copy the code

    This should be familiar to you, but the problem is that the component library code is compiled to use document.queryselectory () for styling. However, when generating static HTML, all pages of VuePress need to be rendered by node.js server. As there is no Document object in node.js environment, when accessing the API in browser /DOM, an error will be reported.

    There is no problem with local development, but build will fail

  • Question 2

    window is not defined

    This problem also arises because the component is written with a Window object, which is not available in Node.js.

To solve

  • The first round

    Vuepress’s official solution is to use vue’s dynamic components,

    <template> <component v-if="dynamicComponent" :is="dynamicComponent"></component> </template> <script> export default { data() { return { dynamicComponent: null } }, mounted () { import('./lib-that-access-window-on-import').then(module => { this.dynamicComponent = module.default }) } }  </script>Copy the code

    For details, see browser API access restrictions

    This is a good way to solve the problem, but it’s a hassle, and I have to document a dozen components, and I have to do this every time I write a demo, and if I have a complex example, and I use several components in a demo, it’s a hassle, it’s not elegant, it’s not elegant.

    And when you document it, the component library can be fully introduced in enhanceapp.js at once, rather than on demand, for example:

    import Element from 'element-ui'
    
    export default ({ Vue, options, router, siteData }) => {
        Vue.use(Element);
    };
    Copy the code
  • The second round

    The first solution already gives us the idea of accessing the browser/DOM API before mounting or mounting.

    However, according to our requirements, we can not handle this problem separately in the Demo component, so we will return to enhanceapp.js, the introduction of the component library can be placed here, where we can use mixin to handle.

    Since it’s node.js server rendering, the first thought was to use require:

    import Element from 'element-ui'
    
    export default ({ Vue, options, router, siteData }) => {
        Vue.use(Element);
        Vue.mixin({
            mounted() {
                var WisdomUI = require('wisdom-ui')
                Vue.use(WisdomUI)
            },
        })
    };
    Copy the code
    • Build by
    • Failed to load components running locally

    ES module should be used:

    import Element from 'element-ui'
    
    export default ({ Vue, options, router, siteData }) => {
       Vue.use(Element);
       Vue.mixin({
           mounted() {
               import('wisdom-ui').then(function (m) {
                   Vue.use(m.default)
               })
           },
       })
    };
    Copy the code
    • There is no problem running locally
    • Build normal

    Problem solved.

Why can’t I use require here to load the component library