使用webpack+babel编译打包一个自己的js库

使用webpack4 + babel7来生成自己的js库,同时加入eslint校验,jsdoc生成,单元测试。

需求

公司之前的js库是手写的,使用的是es5代码,手动做的模块划分,没有模块化的概念,本次使用webpack4 + babel7 来构建这个js库。

如果不使用webpack,babel可以单独的转译单个es6文件为es5代码,但是没有模块化的功能,这里结合webpack和babel,可以实现定制化的需求。

准备

  1. 建立个文件夹,使用如下命令生成packge.json文件
npm init -y
  1. 需要安装如下几个依赖:
webpack   //打包工具
webpack-cli    //webpack4 之后都要装这个
babel-loader    //webpack loader,来处理 es代码
@babel/cli   //babel7
@babel/core
@babel/polyfill 
@babel/runtime
npm i  webpack   webpack-cli   @babel/cli   @babel/core babel-loader  --save-dev
npm i  @babel/polyfill   @babel/runtime --save

3.安装完成之后,我们建立几个子文件夹,如下

+---- build  #放webpack配置文件
+---- dist #打包输出文件
+---- src #源代码文件夹

在src文件夹下建一个lib文件夹文件,在lib文件夹建一个tools.js文件,写几个es6代码:

/* tools.js */
export function getName(){
    return 'abc';
}

然后在src文件index.js文件,引入刚才的tools.js:

/* index.js */
import * as tools from './lib/tools';

export {
    tools
}

相当于导出了一个模块,模块名叫tools, 里面有个函数叫getName

导出

接下来我们要把这个模块导出成es5的代码。

build文件夹新建一个webpack的配置文件webpack.config.js, 内容如下:

const path = require('path');

module.exports ={
    mode: 'production', // 生产环境,压缩代码
    entry: ['./src/index.js'], //入口
    output: {
        library: 'oreo', // 库名字, 取名叫oreo(奥利奥), 可以直接调用,比如window.oreo
        libraryTarget: 'umd', // 输出library规范代码, umd是兼容amd和cmd的
        path: path.resolve(__dirname, '../dist'), // 输出路径
        filename: 'oreo.js' // 文件名
    },
    devtool: 'source-map', 
    module: {
        rules: [
            {
                test: /\.js$/,
                include: [
                    path.resolve(__dirname, 'src')
                ],
                exclude: /node_modules/,
                use: {
                    loader: 'babel-loader' // 使用babel-loader处理es代码
                }
            }
        ]
    }
};

执行命令,就可以生成了。

webpack --config build/webpack.config.js

或者直接把这个命令行放到package.jsonnpm scripts里面

"scripts": {
    "build": "webpack --config build/webpack.config.js"
}

直接执行npm run build就可以了,webapck就会把编译好的文件输出在dist文件夹。

可以直接被html引用:

<script src="../dist/oreo.js"></script>
<script>
    console.log(oreo.tools.getName()); //输出abc
</script>

也可以直接用作模块被其他模块使用import导入

package.json 的项目入口文件改成之前定义的index.js

{
    "name": "oreo",
    "version": "0.0.1",
    "description": "oreo测试",
    "main": "src/index.js",
}

发布到npm服务器后,被引入到另外一个项目

import * as orea from 'oreo' ;  //假设我们的模块名字叫oreo,被其他项目引用
console.log(oreo.tools.getName()); //输出abc

为库加入eslint 代码审查

既然是用作js基础库,必定要保证质量,这里用eslint来进行代码审查

安装:

npm i eslint  --save-dev

安装完成时候我们在根目录建一个.eslintrc.js文件。该文件是eslint的配置文件

module.exports = {
    env: { //环境
        browser: true,
        es6: true
    },
    extends: "eslint:recommended",  // 官方推荐的校验配置
    globals: { // 预设一些全局变量,eslint校验这些
        "Atomics": "readonly",
        "SharedArrayBuffer": "readonly"
    },
    parserOptions: {
        "ecmaVersion": 2018,
        "sourceType": "module"
    },
    rules: { // 规则
       /* 风格 */
        'indent': [0, 4], // 4个空格缩进
        'semi': [1, 'always'], // 结尾使用分号
    }
};

我们可以在package.jsonnpm scripts里面加入命令行:

// eslint命令后面是要审查的目录
"scripts": {
      "lint": "eslint src/**"
}

执行npm run lint,就可以查看控制台的校验信息了,如果不符合rules定义的规范,控制台会打印一下信息。具体的配置可以到 eslint中文网查看详细文档。

我们也可以在webpack生成之前做审核,这个需要eslint-loader插件,我们来安装它

npm i eslint-loader --save-dev

我们在webpack.config.js里面加入eslint-loader

    module: {
        rules: [
            {
                //前置(在执行编译之前去执行eslint-loader检查代码规范,有报错就不执行编译)
                test: /.(js)$/,
                enforce: 'pre', // 在执行编译之前去执行eslint-loader检查代码规范,有报错就不执行编译
                exclude: /node_modules/,
                loader: "eslint-loader",
                options: { 
                    formatter: function(results) {
                        return "output";
                    }
                }
            }
            // ...其他代码
        ]
    },

执行npm run build 就可以在编译之前进行eslint校验了。

根据jsdoc生成文档

jsdoc是一个js注释生成文档的方案,最新版是jsdoc3,ink-docstrap是配套的一个主题,我们可以使用jsdoc3+ ink-docstrap来自动生成js文档。

首选安装它们

npm i jsdoc ink-docstrap --save-dev

然后我们在项目根目录创建一个名字为docs的文件夹, 用来放置我们输出的文档。然后在项目根目录再建一个jsdoc的配置文件jsdoc.config.json

{
  "tags": {
    "allowUnknownTags": true // 允许未知的tag
  },
  "source": {
    "include": [  //需要生成文档的文件夹列表
      "src"
    ],
    "exclude": [  //排除某些文件
      "src/index.js",
      "src/whale.js"
    ],
    "includePattern": ".+\\.(js|es)$"    //正则匹配的文件才会被生成文档
  },
  "plugins": [
    "plugins/markdown"   // markdown插件
  ],
  "markdown": {  // markdown配置
    "tags": [
      "file"
    ],
    "excludeTags": [
      "author"
    ],
    "parser": "gfm",
    "hardwrap": true
  },
  "templates": {
    "cleverLinks": false,
    "monospaceLinks": false,
    "dateFormat": "ddd MMM Do YYYY",
    "outputSourceFiles": true,
    "outputSourcePath": true,
    "systemName": "common文档", // 标题
    "footer": "",
    "copyright": "https://docs.qianxiangbank.com", 
    "navType": "inline",
    "theme": "cerulean",  // 主题名,ink-docstrap提供的
    "linenums": true,
    "collapseSymbols": false,
    "inverseNav": true,
    "protocol": "html://",
    "methodHeadingReturns": false
  },
  "opts": {
    "template": "./node_modules/ink-docstrap/template", // 模板路径,ink-docstrap提供的
    "destination": "./docs/", //输出路径
    "recurse": true, //是否递归
    "debug": true,
    "readme": "README.md"  //要转换的readme文件
  }
}

外面直接把启动命令放到package.jsonnpm scripts里面

"scripts": {
    "doc": "jsdoc -c jsdoc.config.json",
}

执行命令 npm run doc 就可以生成文档了。

加入单元测试框架(Karma + Mocha + chai)

为了验证代码写的是否正确,时常需要引入单元测试,这里就为我们的js库引入Karma+Mocha+chai, Karma提供了测试环境,Mocha是单元测试框架,chai是断言库。在这里Karma会启动浏览器环境,运行Mocha测试用例,然后使用chai来进行判断。

首先我们还是需要安装一些东西:

Mocha + chai:

npm i mocha   chai --save-dev

Karma:

npm i karma karma-webpack karma-mocha  karma-chrome-launcher karma-chai --save-dev

我们在项目根目录建一个配置文件,名字叫karma.config.js

// file : karma.config.js
// Karma configuration

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

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

        client: {
            captureConsole: true // 设置由 terminal 捕捉 browser 的输出
        },

        browserConsoleLogOptions: {
            level: "log",
            format: "%b %T: %m",
            terminal: true
        },

        // 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: [
             "./test/*.test.js"  // test文件夹下任意层级的.js文件 将要被测试
        ],

        // 排除文件
        exclude: [
            "karma.config.js"
        ],
        // preprocess matching files before serving them to the browser
        // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
        // 要被浏览器正常的测试,有些js代码需要被转成es5,这里需要定义这个预处理器
        preprocessors: {
            "src/**/*.js": ["webpack"],
            "test/*.test.js": ["webpack"]
        },
        // karma 插件
        plugins: [
            "karma-webpack",
            "karma-mocha",
            "karma-chrome-launcher",
            "karma-chai"
        ],
        webpack: {
            mode: 'development',
            module: {
                rules: [
                    {
                        test: /\.js$/,
                        exclude: /(node_modules|bower_components)/,
                        use: [
                            {
                                loader: 'babel-loader'
                            },
                        ]
                    },
                ]
            }
        },
        webpackServer: {
            noInfo: true
        },
        // test results reporter to use
        // possible values: "dots", "progress"
        // available reporters: https://npmjs.org/browse/keyword/karma-reporter
        reporters: ["dots"],
        // 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_LOG,
        // 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
    })
};

配置文件完成之后,我们需要写一些测试文件。
在根目录下面建一个test文件夹,创建一个toos.test.js文件

import * as tools from "../src/lib/tools";
const expect = require('chai').expect; // chai
describe('tools.js测试', function () {
     describe('getName函数测试', function () {
         it('返回值测试通过', function () {
              expect(tools.getName()).to.be.equal('abc');;
          });
    });
});

我们仍然把启动命令行放到package.jsonnpm scripts里面

"scripts": {
    "test": "karma start karma.config.js",
  },

执行命令npm run test 就可以唤起chrome浏览器进行测试了。
如果控制台没有提示报错,就意味着单元测试通过。

如果我们只需要在node环境下进行测试,其实不需要karma,只需要Mocha+chai 就可以完成了。

"scripts": {
      "mocha-test": "mocha --require @babel/register"
  },

执行命令npm run mocha-test 就可以在node环境下测试了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 198,082评论 5 464
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,231评论 2 375
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 145,047评论 0 327
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,977评论 1 268
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,893评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,014评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,976评论 3 388
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,605评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,888评论 1 293
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,906评论 2 314
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,732评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,513评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,980评论 3 301
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,132评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,447评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,027评论 2 343
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,232评论 2 339