构建Npm模块

前面的话

我们平时都是使用npm仓库中别人的模块,如果我们想自己创建模块并且发布到Npm仓库供别人使用,应该如何操作呢?

Npm仓库的模块特点
  • 在每个模块根目录下都应该必须有一个描述该模块的package.json文件
  • 模块中的文件已JavaScript文件为主,但不限于JavaScript文件,也可以同时有JavaScript、css、图片文件
  • 模块最好遵守CommonJs模块化规范(目前支持比较广泛)
实例

webpack不仅可以构建可运行的应用,也可以构建可上传到npm的模块。下面通过一个实例来具体说明:

编写一个可上传到Npm仓库的React组件,要求如下:

  • 源码采用es6编写,但发布到Npm仓库时需要转为es5,并且遵守CommonJS模块化规范,提供Source Map以方便调试
  • 该组件依赖的其他资源,如css文件也应该包含在其中
  • 减少代码的冗余,减少发布出去的代码大小
  • 发布出去的组件的代码中不含其他依赖的模块的代码
简单的React组件

第一步:写一个简单的React组件,源码都放在src目录下:
在这里插入图片描述
index.js文件:

import React, {Component} from 'react';
import './index.css';
// 导出该组件以供其他模块使用
export default class HelloWebpack extends Component {
    render() {
        return <h1 className="hello-component">Hello,Webpack</h1>
    }
}

index.css文件:

.hello-component {
     color: red;
     background: black;
 }
使用webpack构建Npm模块

依照上面的4点要求,给出解决方法:

  • 要求一: 使用babel-loader将es6代码转换为es5代码; 配置.babelrc文件; 开启devtool:‘source-map’; 设置output.libraryTarget: ‘commonjs2’,使代码符合CommonJS2模块化规范。

    webpack相关配置如下:

     module.exports = {
     output:{
     	 //  以commonjs2规范导出,以供其他模块使用
        libraryTarget: 'commonjs2'
     	},
      module: {
        rules: [
            {
                test: /\.js$/,
                use: ['babel-loader'],
                // 排除 node_modules 目录下的文件
                // node_modules 目录下的文件都是采用的 ES5 语法,没必要再通过 Babel 去转换
                exclude: path.resolve(__dirname, 'node_modules'),
            }]
          }
     	 // 输出Source Map
    	devtool: 'source-map'
    }
    

    .babelrc文件相关配置如下:

    {
        "presets": [
            "env",
            "react"
        ],
     }
    
  • 要求二: 将css文件打包,通过css-loader,与mini-css-extract-plugin实现。

    webpack相关配置如下:

    const MiniCssExtractPlugin = require('mini-css-extract-plugin');
     // 在module的rules中添加
     module: {
        rules: [
            {
                test: /\.js$/,
                // 省略
               
            },
            {
            // 增加对css的支持
            test: /\.css/,
            // 提取出Chunk中的css代码到单独的文件
            use: [
                MiniCssExtractPlugin.loader,
                'css-loader'
            ]
        }]
    },
       plugins: [
        new MiniCssExtractPlugin({
            filename: 'index.css'
        })
    ],
    
  • 要求3:在es6转es5时代码会注入一些辅助函数,如果多个文件都依赖这些辅助函数,那么这些辅助函数的代码会重复出现多次,为减少代码冗余,可以使用babel-plugin-transform-runtime插件来使这些辅助函数只出现一次。

     注意:babel-plugin-transform-runtime插件要配合使用babel-runtime模块使用。
     
     修改.babelrc文件:
    
     "plugins": [
            [        
            "transform-runtime",
            {
                /*transform-runtime 默认会自动为我们使用es6 API注入polyfill ,
                 假如我们在源码中使用了Promise,则输出的代码将会自动注入require('babel-runtime/core-js/Promise')语句,
                 polyfill的注入应该交给模块的使用者,因为使用者可能在其他地方注入了其他Promise Polyfill库,所以关闭这个功能
                 */
                 "polyfill": false
    
                 // 加入babel-plugin-transform-runtime后,需要与babel-runtime一起配合使用
            }
            ]
        ]
    
  • 要求4: 使用externals来告诉webpack哪些模块时外部环境提供的,不需要被打包,时webpack在打包时将它们忽略。

    webpack相关配置:

    	module.exports = {
    	// 通过正则命中所有以react或者babel-runtime开头的模块,这些模块通过注册在运行环境中的全局变量访问,不用
    	    // 被重复打包进输出的代码里
    	    externals: /^(react|babel-runtime})/,	
    	 }
    
完整的webpack配置文件

上面根据要求分别给出了解决的方法,下面是webpack配置文件的完整代码:

const  path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
    entry: './src/index.js',
    output: {
        filename: 'index.js',
        // 输出文件存放目录
        path: path.resolve(__dirname, 'lib'),
        // 以何种方式导出库
        libraryTarget: 'commonjs2'
    },
    // 通过正则命中所有以react或者babel-runtime开头的模块,这些模块通过注册在运行环境中的全局变量访问,不用
    // 被重复打包进输出的代码里
    externals: /^(react|babel-runtime})/,
    module: {
        rules: [
            {
                test: /\.js$/,
                use: ['babel-loader'],
                // 排除 node_modules 目录下的文件
                // node_modules 目录下的文件都是采用的 ES5 语法,没必要再通过 Babel 去转换
                exclude: path.resolve(__dirname, 'node_modules'),
            },
            {
            // 增加对css的支持
            test: /\.css/,
            // 提取出Chunk中的css代码到单独的文件
            use: [
                MiniCssExtractPlugin.loader,
                'css-loader'
            ]
        }]
    },
    plugins: [
        new MiniCssExtractPlugin({
            filename: 'index.css'
        })
    ],
    // 输出Source Map
    devtool: 'source-map'
}

需要引入的依赖如下:
在这里插入图片描述

执行构建

执行构建之后,我们在项目目录下会看到新目录lib,里面放着要发布到Npm仓库的最终代码。
在这里插入图片描述

发布到Npm

将构建的代码发布到Npm仓库前,我们需要修改package.json文件:
由于构建出的代码的入口文件上是:./lib/index.js,所以我们要修改package.json中的main字段:

 // 构建出的代码入口文件是:"./lib/index.js",将代码发到Npm仓库前,需要修改main字段
  "main": "./src/index.js",
  // jsnext:main字段用于指出ES6编写的模块入口所在的位置
   "jsnext:main": "src/index.js",

修改完毕后,执行npm login之后,再执行npm publish ,就能将构建出的代码发布到Npm仓库中。之后就可以自行下载这个模块,放在其他应用中使用。

完整项目地址:构建Npm模块

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值