构建组件库

目录结构

.
├── .babelrc
├── .browserslistrc
├── .editorconfig
├── .eslintignore
├── .eslintrc.js
├── .gitignore
├── README.md
├── build
│   ├── webpack.base.config.js
│   ├── webpack.prod.config.js
│   ├── webpack.prod.dev.config.js
│   └── webpack.test.config.js
├── commitlint.config.js
├── docs
│   ├── .vuepress
│   │   ├── components
│   │   ├── config.js
│   │   ├── dist
│   │   └── enhanceApp.js
│   ├── README.md
│   └── components
│       └── README.md
├── package.json
├── postcss.config.js
├── src
│   ├── components
│   └── index.js
├── test
│   ├── .eslintrc.js
│   └── unit
│       ├── index.js
│       ├── karma.conf.js
│       ├── specs
│       └── util.js
└── yarn.lock

使用到的 loader

  • css-loader:将 @importurl() 按照import/require()的方式解析
  • style-loader:将通过 import/require() 引入的 css 插入到页面的 style 标签中
  • vue-style-loaderstyle-loader 的 fork):将通过 import/require() 引入的 css 插入到页面的 style 标签中
  • less-loader:将 Less 编译为 CSS
  • sass-loader:将 Sass 编译为 CSS
  • babel-loader:使用 Babel 编译 JavaScript
  • url-loader:处理 import/require()引入的文件,大于 limit 参数规定大小的文件调用 file-loader处理(发送到输出路径);小于 limit 参数规定大小的文件返回 DataURL
  • html-loader:处理 HTML文件

使用到的 plugins

babel 相关

依赖

  • babel-loader:使用 BabelWebpack 编译 JavaScript 的 loader,依赖于 @babel/core
  • @babel/coreBabel 编译的核心,相当于 Babel 的 API。
  • @babel/preset-env:官方提供的一个 preset

配置

.babelrc

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

转码规则:

  • 官方提供的几个常用的环境:
    • @babel/preset-env
    • @babel/preset-flow
    • @babel/react
    • @babel/preset-typescript
  • 自己创建

注意:

  • Babel7 已经移除了 Yearly Preset(如:babel-preset-es2015) 和 Stage Preset(如: babel-stage-2
  • Babel7@babel/preset-react 更名为 ``@babel/react`

本项目采用的是 @babel/preset-env preset。

@babel/preset-env 会根据你配置的 targets(也就是浏览器环境)自动选择编译 JavaScript 要用的插件。

.browserslistrc

> 1%
last 2 versions
ie >= 8

配置项目运行的目标浏览器环境。有许多工具会用到这个文件,如:autoprefixerstylelint……

@babel/preset-env 也会用到这个配置,@babel/preset-env 使用 browserslistnpm 包来读取目标环境配置。browserslist 读取配置的其中一种方式就是使用 .browserslistrc 文件,本项目采用这种方式。

该项目配置说明:

> 1%

 全球有 1% 以上的人使用的浏览器版本

last 2 versions

最新的两个版本

ie >= 8

IE 8 及以上

提示:使用 npx browserslist 可以列出查询条件筛选出的浏览器

关于 browserslist 的配置说明  以及  更多详细使用方法,可以在 github 上查看。

webpack 配置

webpack.base.config

/**
 * 公共配置
 */
const path = require('path')
const VueLoaderPlugin = require('vue-loader/lib/plugin')

const config = {

  // 模块
  module: {

    // 匹配请求的规则
    rules: [
      {
        test: /\.vue$/,
        loader: 'vue-loader',
        options: {
          sourceMap: true
        }
      },
      {
        test: /\.js$/,
        loader: 'babel-loader',
        options: {
          sourceMap: true
        },
        exclude: /node_modules/
      },
      {
        test: /\.css$/,
        loaders: [
          {
            loader: 'vue-style-loader',
            options: {
              sourceMap: true
            }
          },
          {
            loader: 'css-loader',
            options: {
              sourceMap: true
            }
          }
        ]
      },
      {
        test: /\.less$/,
        loaders: [
          {
            loader: 'vue-style-loader',
            options: {
              sourceMap: true
            }
          },
          {
            loader: 'css-loader',
            options: {
              sourceMap: true
            }
          },
          {
            loader: 'less-loader',
            options: {
              sourceMap: true
            }
          }
        ]
      },
      {
        test: /\.scss$/,
        loaders: [
          {
            loader: 'vue-style-loader',
            options: {
              sourceMap: true
            }
          },
          {
            loader: 'css-loader',
            options: {
              sourceMap: true
            }
          },
          {
            loader: 'sass-loader',
            options: {
              sourceMap: true
            }
          }
        ]
      },
      {
        test: /\.(gif|jpg|png|woff|svg|eot|ttf)\??.*$/,
        loader: 'url-loader',
        options: {
          limit: 8192
        }
      },
      {
        test: /\.html$/,
        loader: 'html-loader'
      }
    ]
  },

  // 解析
  resolve: {
    extensions: ['.js', '.vue'],
    alias: {
      '@': path.join(__dirname, '..', 'src')
    }
  },

  // 插件
  plugins: [
    new VueLoaderPlugin() // Vue Loader v15 现在需要配合这个 webpack 插件才能正确使用
  ]
}

module.exports = config

rules

  • 处理 .vue 文件使用了 vue-loader
  • 处理 .js 文件使用了 babel-loader
  • 处理 .css 文件先后使用了
    • css-loader
    • vue-style-loader
  • 处理 .less 文件先后使用了
    • less-loader
    • css-loader
    • vue-style-loader
  • 处理 .scss 文件先后使用了
    • sass-loader
    • css-loader
    • vue-style-loader
  • 处理图片、字体等使用了 url-loader,并设置 limit 为 8192:大于 8192 B(Byte)的文件调用 file-loader处理(发送到输出路径);小于 8192 B 的文件返回 DataURL
  • 处理 .html文件使用了 html-loader

注意:Vue Loader v15 使用了一个不一样的策略来推导语言块使用的 loader,例如,会把 <style lang="less"> 当作一个真实的 .less 文件来加载,也就是会匹配对 .less 配置的 rules,因此无需再  配置 vue-loader 配置中的 loaders(并且该配置在 v15 中也被弃用)。

resolve

  • extensions:自动解析确定的扩展,能够使用户在引入模块时不带扩展。
  • alias:创建 importrequire 的别名,来确保模块引入变得更简单。

webpack.prod.config

/**
 * 构建生产环境包
 */
const path = require('path')
const merge = require('webpack-merge')
const webpackBaseConfig = require('./webpack.base.config.js')
const pkg = require('../package.json')

const name = pkg.name

const config = {

  // 模式
  mode: 'production',

  // 入口
  entry: {
    main: './src/index.js'
  },

  // 出口
  output: {
    path: path.resolve(__dirname, '../dist/prod'),
    publicPath: '/dist/',
    filename: name + '.js',
    library: name, // 模块名称
    libraryTarget: 'umd', // 输出格式
    umdNamedDefine: true // 对 UMD 的构建过程中的 AMD 模块进行命名
  },

  // 外部扩展
  externals: {
    vue: {
      root: 'Vue',
      commonjs: 'vue',
      commonjs2: 'vue',
      amd: 'vue'
    },
    'element-ui': {
      root: 'ELEMENT',
      commonjs: 'element-ui',
      commonjs2: 'element-ui',
      amd: 'element-ui',
    }
  },
}
module.exports = merge(webpackBaseConfig, config)



webpack.base.config 的基础上增加配置。

说明:

  • mode: 'production':模式设置为生产环境,webpack 会自动针对生产环境进行优化。
  • externals:外部扩展。从输出的 bundle 中排除依赖。防止将某些 import 的包(package)打包到 bundle 中,而是在运行时(runtime)再去从外部获取这些扩展依赖(external dependencies)。

webpack.prod.dev.config

/**
 * 构建开发版生产环境包
 */

const path = require('path')
const merge = require('webpack-merge')
const webpackBaseConfig = require('./webpack.base.config.js')
const pkg = require('../package.json')

const name = pkg.name

const config = {
  mode: 'development',

  // 入口
  entry: {
    main: './src/index.js'
  },

  // 出口
  output: {
    path: path.resolve(__dirname, '../dist/prod.dev'),
    publicPath: '/dist/',
    filename: name + '.dev.js',
    library: 'comp', // 模块名称
    libraryTarget: 'umd', // 输出格式
    umdNamedDefine: true // 是否把模块名作为AMD输出的命名空间
  },

  // 外部扩展
  externals: {
    vue: {
      root: 'Vue',
      commonjs: 'vue',
      commonjs2: 'vue',
      amd: 'vue'
    }
  }
}
module.exports = merge(webpackBaseConfig, config)

 开发版的生产环境包与前面的生产环境包唯一的改变就是将 mode 修改  为 development,避免 webpack 对代码进项压缩,以方便使用者调试。

webpack.test.config

/**
 * 单元测试
 */

const merge = require('webpack-merge')
const webpackBaseConfig = require('./webpack.base.config.js')
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')

const config = {

  // 模式
  mode: 'development',

  // 插件
  plugins: [new FriendlyErrorsPlugin()]
}

module.exports = merge(webpackBaseConfig, config)

单元测试不需要入口出口,只是增加了一个 friendly-errors-webpack-plugin 的插件,使控制台的输出更加友好。

单元测试

使用 karma + mocha + chai

karma 配置:karma.conf.js

const webpackConfig = require('../../build/webpack.test.config')

// Karma configuration
// Generated on Fri Jan 18 2019 17:21:29 GMT+0800 (GMT+08:00)

module.exports = function(config) {
  config.set({

    // base path that will be used to resolve all patterns (eg. files, exclude)
    basePath: '',

    // frameworks to use
    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
    frameworks: ['mocha', 'chai'],

    // list of files / patterns to load in the browser
    files: ['./index.js'],

    // list of files / patterns to exclude
    exclude: [],

    // preprocess matching files before serving them to the browser
    // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
    preprocessors: {
      './index.js': ['webpack']
    },

    webpack: webpackConfig,

    // test results reporter to use
    // possible values: 'dots', 'progress'
    // available reporters: https://npmjs.org/browse/keyword/karma-reporter
    reporters: ['spec'],

    // web server port
    port: 9876,

    // enable / disable colors in the output (reporters and logs)
    colors: true,

    // level of logging
    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
    logLevel: config.LOG_INFO,

    // enable / disable watching file and executing tests whenever any file changes
    autoWatch: true,

    // start these browsers
    // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
    browsers: ['Chrome'],

    // Continuous Integration mode
    // if true, Karma captures browsers, runs the tests and exits
    singleRun: false,

    // Concurrency level
    // how many browser should be started simultaneous
    concurrency: Infinity
  })
}

参考:

最后更新时间: 3/25/2019, 4:08:34 PM