记一次webpack + ts 发包

背景

前段时间写过一篇 一文拿下Web端基于AudioWorkletNode录制音频 , 然后现在毕设什么的都搞定了比较闲, 就来琢磨怎么将其发包(主要是想重操一下发包流程),此篇整理详细记录实现过程, 以防自己以后多走弯路

搞定npm

要发布一个npm包首先你要有对应的npm账号, 这里就不赘述了

在操作之前, 先通过npm get registry确认是否为官方源

  • 若显示为: https://registry.npmjs.org/则为官方源
  • 若显示为: https://registry.npmmirror.com 或者 https://registry.npm.taobao.org(过期了的)则为淘宝源, 此时如果你登录的话其实是登录cnpm, 故需要可通过npm config set registry https://registry.npmjs.org进行切换

接着呢, 在命令行输入npm login 或者npm adduser进行登录,显示如下或者让你输入账密登录,跟着流程走就好 想确认是否登录成功可以通过npm whoami, 如已经登录了的话则会显示你的账号名称

关键步骤

建包

新建一个文件夹并使用npm init,会让你输入一些关键属性接着生成package.json,以下为发包可能涉及到的一些属性

  • name: 该包的名称
  • description: 该包的简述
  • main: 该包的入口文件
  • scripts: 定义一组可以运行的node脚本
  • author:作者名
  • contributors: 贡献者
  • keywords: 一组关键词, 影响搜索
  • repository: 指定仓库链接
  • private: 如果设置为 true,则可以防止应用程序/软件包被意外地发布到 npm。 故这里要么不指定要么设置为false
  • files: 可以通过 files 指定需要跟随一起发布的内容来控制npm 包的大小,避免安装时间太长

当然这里如果想更详细地了解package.json的属性, 指路: package.json 配置完全解读 - 掘金 (juejin.cn)

发布

当业务内容都搞完了就可以发布了, 在发布之前需要先检查一下包名称是否有问题, npm是不允许有同名的包, 当你发包时,若已有同名的包那么就会失败

可以先通过npm search搜索是否已有同名包, 若有符合的包名称则会显示相关信息, 匹配上的包名称还会标红。 如果此时发现有同名的包, 那么就修改package.json中的name以修改包名称。注意包名称不能出现下划线、大写字母、空格等字符,可以有连字符和中划线。

发布的话则使用npm publish就OK了。 在发包的时候会显示该包内包含了什么文件,以及相关的包的信息。 一般来说除了package.json中通过files指定的目录之外, 还会带上整体的README文件和package.json文件

当然发包偶尔就会失败(超时).... 多试几次就好了

更新

当包内容有更新时, 直接使用npm publish是会失败的,因为此时的版本号与现有的版本号重复了。

故需要先更新版本号, 有两个方法可以修改版本号:

  • 直接修改package.jsonversion属性
  • 通过命令行npm version [option]更新版本号, 主要option如下
    • major: 主版本号 -- 大更新 1.0.0 -> 2.0.0
    • minor: 次版本号 -- 小更新 1.0.0 -> 1.1.0
    • patch: 补丁版本号 -- 打补丁 1.0.0 -> 1.0.1
    • premajor: 预备主版本
    • preminor: 预备次版本
    • prepatch: 预备补丁版本

当然还有包的撤销和弃用, 这按需搜索就好了

结合内容

这个包的内容很简单, 基本源代码就是之前文章内写的。记录也不是为了记录源码内容, 而是其他步骤。

src目录下即为核心代码, index.ts文件作为入口文件。

.d.ts声明文件

发布一个包最好要生成对应的 .d.ts 文件,提供代码补全和接口提示的功能, 没提供的话一般IDE会有报错提醒。

在该项目中我们是通过@babel/preset-typescript去处理TS文件的, 但是@babel/preset-typescript在处理typescript的时候是没有提供生成声明文件这个功能的, 故可以通过tsc --emitDeclarationOnly去生成声明文件。

或者使用ts-loader去处理, 这个就直接提供声明文件

搞定声明文件后, 需要在package.jsontypes字段去指定声明文件: "types": "dist/main.d.ts",

webpack配置

源码使用webpack作为打包工具,内部主要提供三条命令, 根据不同的命令使用不同的webpack配置文件

  • demo: 构建生成demo, 可以通过HTML文件直接体验效果
  • dev:开发中用于调试功能, 使用webpack-dev-server
  • build: 构建生成发包产物

使用webpack需要先进行安装npm install --save-dev webpack webpack-cli

对于build构建而言, 命令行为: webpack --mode=production, 默认的配置文件为webpack.config.js

js 复制代码
const { join } = require('path');
const CopyPlugin = require('copy-webpack-plugin');
module.exports = {
    entry: join(__dirname, './src/index.ts'), // 打包入口
    output: {
        filename: '[name].js',  // 产物名称
        // 产物目录
        // 这里都收归到dist目录下, 最后发包的package.json指定files为dist即可
        path: join(__dirname, './dist'), 
        // 每次构建齐纳都先清空dist目录
        clean: true,
        publicPath: '/',
        // 暴露从入口导出的内容, 如果你构建之后发现产物基本没东西那么就是忘记配置这个了
        library: {  
            name: '"webAudioRecorder', // 构建产物的名称, 这里需要与入口数量匹配
            type: 'umd' // 构建产物支持的方式, 
        },
    },
    resolve: {
         // webpackh会尝试按顺序解析这些后缀名, 列入使用到的文件后缀即可
        extensions: ['.ts','.js']
    },
    plugins: [
        // 业务内容中涉及到process.js文件是通过addModule的方法
        // 放在Web Audio rending thread中运行
        // 在构建中webpack是识别不到他的, 故需要将它复制到产物中, 这里使用CopyPlugin
        //类型文件同理
        new CopyPlugin({
            patterns: [{
                from: './src/recorder/processor.js',
                to: './processor.js'
            }, {
                from: './index.d.ts',
                to: './main.d.ts',
            }]
        })
    ],
     optimization: {
        minimize: false  // 是否压缩,这里看个人需求就好了
    },
    // 这里就使用babel处理, 没啥了
    module: {
        rules: [
            {
                test: /.(ts)$/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: [
                            '@babel/preset-env', 
                            '@babel/preset-typescript'
                        ]
                    }
                },
            }
        ],
    },
}

output.library.type支持的类型指步:output.library.type

对于devdemo而言, 录音功能其实通过一些按钮调用就好了, 故先在example目录下生成对应的HTML的模板以及对应的调用文件。 如果是开发中, 调用文件则使用src目录下的代码。 如果是生成demo的话, 则调用dist目录下的构建产物(如果发版了也可以使用包产物)。

dev的命令行则使用webpack-dev-server去启动dev": "webpack-dev-server --mode=development --config webpack.dev.js"

demo的命令行则使用webpack去启动"demo": "webpack --mode=production -c webpack.dev.js"

两者的配置文件都为webpack.dev.js

js 复制代码
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyPlugin = require('copy-webpack-plugin');
module.exports = {
    // 入口
    entry: path.join(__dirname, './example/index.js'),  // 调用文件作为入口
    devtool: 'source-map',
    devServer: {
        port: 3000, // 服务端口号
        hot: true, // 开启热更新
        host: 'localhost',  // 在本项目中,相关API需要在安全上下文调用, 故需要指定host
        historyApiFallback: true, // 解决history路由404问题
    },
    output: {
      filename: 'index.js',
      clean: true,
      path: path.join(__dirname, './demo')  // 构建产物放在demo
    },
    module: { ... }, // 省略
    resolve: { ... }, // 省略
    plugins: [
        // 使用模板HTML , 生成产物
        new HtmlWebpackPlugin({
            template: path.resolve(__dirname, './example/index.html'),
            filename: 'index.html',
            inject: true
        }),
        // 将静态资源copy过去
        new CopyPlugin({
            patterns: [{
                from: './src/recorder/processor.js',
                to: './processor.js'
            }]
        })
    ]
};

当然如何要应用在其他项目中进行测试, 还可以用npm link相关功能。 比如在开发业务专属eslint规则包的时候, 直接npm link过去业务项目中测试会高效很多

相关推荐
江号软件分享25 分钟前
有效保障隐私,如何安全地擦除电脑上的敏感数据
前端
web守墓人1 小时前
【前端】ikun-markdown: 纯js实现markdown到富文本html的转换库
前端·javascript·html
Savior`L2 小时前
CSS知识复习5
前端·css
许白掰2 小时前
Linux入门篇学习——Linux 工具之 make 工具和 makefile 文件
linux·运维·服务器·前端·学习·编辑器
中微子6 小时前
🔥 React Context 面试必考!从源码到实战的完整攻略 | 99%的人都不知道的性能陷阱
前端·react.js
中微子7 小时前
React 状态管理 源码深度解析
前端·react.js
加减法原则8 小时前
Vue3 组合式函数:让你的代码复用如丝般顺滑
前端·vue.js
yanlele9 小时前
我用爬虫抓取了 25 年 6 月掘金热门面试文章
前端·javascript·面试
lichenyang4539 小时前
React移动端开发项目优化
前端·react.js·前端框架
你的人类朋友9 小时前
🍃Kubernetes(k8s)核心概念一览
前端·后端·自动化运维