阐述 Vue CLI 中的构建目标(Build Target)及其在构建不同类型应用(如库、Web Component)时的作用。

各位观众,各位朋友,老铁们,晚上好!我是今天的主讲人,很高兴能和大家一起聊聊Vue CLI里的那些“构建小目标”。

今天咱们要聊的是Vue CLI的构建目标,也就是--target 这个命令行参数。别看它貌不惊人,但用对了,能让你构建各种类型的Vue应用,从简单的Web应用到复杂的组件库,甚至是能在任何地方运行的Web Components,都离不开它。

一、啥是构建目标?

简单来说,构建目标就是告诉Vue CLI,你最终想要得到什么样子的东西。你想打包成一个可以运行在浏览器里的WebApp?还是一个可以被别人引入的JavaScript库?亦或是一个独立的Web Component? target 参数就是用来指明这个目标的。

Vue CLI默认的构建目标是app,也就是构建一个标准的Web应用。但如果我们想构建其他类型的应用,就需要使用不同的构建目标。

二、构建目标有哪些?

Vue CLI提供了几个常用的构建目标,分别是:

  • app:构建一个标准的Web应用(默认值)。
  • lib:构建一个UMD库。
  • wc:构建一个Web Component。
  • wc-async:构建一个异步加载的Web Component。

咱们一个一个来细说。

三、app 目标:构建Web应用

这个是最常用的,也是默认的。当你运行vue-cli-service build命令时,如果没有指定--target参数,就会使用app目标。它会将你的Vue代码打包成可以在浏览器中运行的HTML、CSS和JavaScript文件。

vue-cli-service build

这个命令会生成一个dist目录,里面包含了构建好的Web应用。

四、lib 目标:构建UMD库

如果你想把你的Vue组件或模块打包成一个可以被其他项目引入的库,那么lib目标就是你的好帮手。 它会生成一个UMD (Universal Module Definition) 格式的JavaScript文件,这种格式可以在各种环境下使用,无论是CommonJS、AMD还是直接在浏览器中通过<script>标签引入。

要使用lib目标,你需要指定一个入口文件和一个库名。入口文件是你库的入口点,库名是你在其他项目中引入时使用的名称。

例如,假设你有一个名为MyComponent.vue的组件,你想把它打包成一个名为my-component的库。你可以这样做:

  1. 创建src/MyComponent.vue

    <template>
      <div>
        <h1>Hello from My Component!</h1>
      </div>
    </template>
    
    <script>
    export default {
      name: 'MyComponent'
    }
    </script>
  2. 创建src/index.js作为入口文件:

    import MyComponent from './MyComponent.vue';
    
    export {
      MyComponent
    };
  3. 运行构建命令:

    vue-cli-service build --target lib --name my-component src/index.js

    解释一下:

    • --target lib:指定构建目标为库。
    • --name my-component:指定库的名称为my-component
    • src/index.js:指定入口文件为src/index.js

构建完成后,你会在dist目录下看到一个my-component.umd.js文件,这就是你的UMD库。 还有一个my-component.umd.min.js是压缩后的版本。

如何使用这个库?

  • 在HTML中使用<script>标签:

    <script src="dist/my-component.umd.js"></script>
    <script>
      // 现在你可以使用 window.myComponent.MyComponent 了
      Vue.component('my-component', window.myComponent.MyComponent);
      new Vue({
        el: '#app',
        template: '<my-component></my-component>'
      })
    </script>
  • 在CommonJS环境中使用 (例如Node.js):

    const { MyComponent } = require('./dist/my-component.umd.js');
    // 现在你可以使用 MyComponent 了
  • 在ES模块环境中使用 (例如Webpack):

    import { MyComponent } from './dist/my-component.umd.js';
    // 现在你可以使用 MyComponent 了

五、wc 目标:构建Web Component

Web Components 是一种可以在任何Web应用中使用的自定义HTML元素。它们具有封装性、可重用性和互操作性等优点。Vue CLI 可以使用wc目标来构建Web Components。

要使用wc目标,你需要指定一个入口文件和一个组件名称。入口文件通常是一个Vue组件,组件名称是你自定义HTML元素的标签名。

例如,假设你有一个名为MyWebComponent.vue的组件,你想把它打包成一个名为my-web-component的Web Component。你可以这样做:

  1. 创建src/MyWebComponent.vue

    <template>
      <div>
        <h1>Hello from My Web Component!</h1>
        <p>Count: {{ count }}</p>
        <button @click="increment">Increment</button>
      </div>
    </template>
    
    <script>
    export default {
      name: 'MyWebComponent',
      props: {
        initialCount: {
          type: Number,
          default: 0
        }
      },
      data() {
        return {
          count: this.initialCount
        }
      },
      methods: {
        increment() {
          this.count++;
        }
      }
    }
    </script>
  2. 创建src/main.js作为入口文件:

    import Vue from 'vue';
    import MyWebComponent from './MyWebComponent.vue';
    
    // Define the custom element using Vue.extend()
    const MyWebComponentConstructor = Vue.extend(MyWebComponent);
    
    // Register the custom element
    customElements.define('my-web-component', MyWebComponentConstructor);
  3. 运行构建命令:

    vue-cli-service build --target wc --name my-web-component src/main.js

    解释一下:

    • --target wc:指定构建目标为Web Component。
    • --name my-web-component:指定组件名称为my-web-component
    • src/main.js:指定入口文件为src/main.js

构建完成后,你会在dist目录下看到一个my-web-component.js文件,这就是你的Web Component。

如何使用这个Web Component?

  1. 在HTML文件中引入my-web-component.js

    <!DOCTYPE html>
    <html>
    <head>
      <title>Web Component Example</title>
    </head>
    <body>
      <my-web-component initial-count="10"></my-web-component>
      <script src="dist/my-web-component.js"></script>
    </body>
    </html>

    注意:你需要将initial-count属性作为props传递给组件。

  2. 在任何支持Web Components的浏览器中打开HTML文件,你就可以看到你的自定义元素my-web-component在运行了。

六、wc-async 目标:构建异步加载的Web Component

wc-async目标与wc目标类似,但它会将Web Component打包成一个可以异步加载的JavaScript文件。这可以提高页面的加载速度,特别是当你的Web Component比较大时。

要使用wc-async目标,你需要做一些额外的配置:

  1. 修改vue.config.js文件:

    module.exports = {
      chainWebpack: config => {
        config.module
          .rule('vue')
          .use('vue-loader')
            .tap(options => {
              options.shadowMode = true // Important for shadow DOM styles
              return options
            })
      },
      css: {
        extract: false
      }
    }
    • chainWebpack: 使用chainWebpack配置webpack,允许你更细粒度地控制webpack的配置。
    • shadowMode = true: 启用 shadow DOM 模式,这对于保证Web Component的样式封装非常重要。
    • css: { extract: false }: 禁用 CSS 提取,因为异步Web Component通常需要将CSS内联到JavaScript中。
  2. 修改src/main.js

    import Vue from 'vue';
    
    export default (props = {}) => new Promise(resolve => {
        import('./MyWebComponent.vue')
            .then(MyWebComponent => {
                const MyWebComponentConstructor = Vue.extend(MyWebComponent.default);
                customElements.define('my-web-component', MyWebComponentConstructor);
                resolve()
            })
    })
    
    • 将组件的导入和注册包装在一个返回 Promise 的函数中。
    • 使用动态 import (import('./MyWebComponent.vue')) 来异步加载组件。
    • 默认导出一个函数,该函数在被调用时才注册自定义元素。
  3. 运行构建命令:

    vue-cli-service build --target wc-async --name my-web-component src/main.js

构建完成后,你会在dist目录下看到一个my-web-component.js文件。

如何使用这个异步加载的Web Component?

  1. 在HTML文件中引入my-web-component.js,并调用导出的函数:

    <!DOCTYPE html>
    <html>
    <head>
      <title>Async Web Component Example</title>
    </head>
    <body>
      <my-web-component initial-count="20"></my-web-component>
      <script src="dist/my-web-component.js"></script>
      <script>
        myWebComponent().then(() => {
            console.log('Web Component loaded!')
        })
      </script>
    </body>
    </html>
    • 引入 my-web-component.js 文件。
    • 调用默认导出的函数 myWebComponent(),并使用 .then() 处理 Promise 的 resolve,确保组件在加载完成后再进行其他操作。

七、构建目标总结

为了方便大家理解,我把这几个构建目标整理成一个表格:

构建目标 描述 用途
app 构建一个标准的Web应用。 构建单页应用 (SPA) 或多页应用。
lib 构建一个UMD库,可以在各种环境下使用。 将Vue组件或模块打包成可重用的库,方便其他项目引入。
wc 构建一个Web Component,可以在任何Web应用中使用。 创建自定义HTML元素,实现封装性、可重用性和互操作性。
wc-async 构建一个异步加载的Web Component,可以提高页面加载速度。 构建大型的Web Component,需要延迟加载以提高性能。

八、一些注意事项

  • 在使用libwc目标时,一定要指定正确的入口文件和名称。
  • wc-async需要额外的配置,特别是vue.config.js文件。
  • 构建Web Component时,需要注意样式封装的问题,可以使用Shadow DOM或者CSS Modules。
  • 根据你的项目需求选择合适的构建目标,可以提高开发效率和应用性能。

九、高级技巧

  • 多入口构建: 你可以使用多个入口文件来构建多个库或Web Components。 例如,你想同时构建MyComponent.vueAnotherComponent.vue 为两个独立的库。

    // vue.config.js
    module.exports = {
      configureWebpack: {
        entry: {
          'my-component': './src/MyComponent.vue',
          'another-component': './src/AnotherComponent.vue'
        },
        output: {
          libraryTarget: 'umd',
          library: '[name]' // 使用入口名称作为库名称
        }
      }
    }

    然后运行 vue-cli-service build,Vue CLI 会根据你的 vue.config.js 配置,分别构建 my-component.umd.jsanother-component.umd.js

  • 自定义 Webpack 配置: 通过 vue.config.js 文件,你可以完全控制 Webpack 的配置,以满足更高级的需求。 例如,你想添加额外的 Babel 插件或修改输出目录。

十、总结

今天咱们聊了Vue CLI中的构建目标,包括applibwcwc-async。 不同的构建目标适用于不同的场景,选择合适的构建目标可以让你更好地构建各种类型的Vue应用。希望今天的分享对大家有所帮助!

好了,今天的讲座就到这里,谢谢大家! 如果有什么问题,欢迎随时提问。下次再见!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注