Webpackコンポーネントライブラリパッケージング超詳細ガイド

一緒に書く習慣をつけましょう!「ナゲッツデイリーニュープラン・4月アップデートチャレンジ」に参加して4日目です。クリックしてイベントの詳細をご覧ください

この記事では、コンポーネントライブラリをWebpackで最初からパッケージ化するプロセスについて説明します。

1.プロジェクトを初期化します

vue init webpack-simple tip-components
复制代码

ディレクトリ構造を最適化する

プロジェクト構造を変更します。次のディレクトリ構造は比較的明確で合理的です。

パッケージ構成用の新しいビルド、ドキュメントを保存するためのdoc、およびパッケージ出力ファイルを保存するためのlibを作成しました。

ディレクトリ構造

2.パッケージ構成

さまざまな要件のパッケージ構成をさまざまなファイルに配置することをお勧めします。

パッケージ構成には基本クラスファイルがあり、さまざまなパッケージ要件に応じて、完全なコンポーネントライブラリパッケージ、単一コンポーネントパッケージ、パッケージサンプルプロジェクトなどのさまざまなサブクラスファイルがあります。

npmでscriptスクリプトを構成することにより、パッケージ化コマンドを簡素化します。

パッケージコマンド

(コマンドは何をしますか、どの構成ファイルを選択するか、package.jsonを参照してください)

サンプルプロジェクトを実行する npm run test

完全なコンポーネントライブラリをパッケージ化する npm run build

個々のコンポーネントをパッケージ化する npm run build:components

コンポーネントドキュメントを生成する npm run build:doc

*パッケージ化コマンドを追加し、プラグインを:analyze有効にすると、パッケージ化が完了するとバンドル分析ページが開きます。webpack-bundle-analyzer

主に次の3つのパッケージ構成ファイルを見ていきます。

webpack.base.js

ルール構成モジュールのルールの読み取りと解析、およびwebpack-bundle-analyzerプラグインを含む一般的なwebpack構成。

//webpack.base.js
var path = require('path')
var webpack = require('webpack')
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin

module.exports = {
  module: {
    rules: [
    //……
    ]
  }
}

if (process.env.npm_config_report) {
  module.exports.plugins = (module.exports.plugins || []).concat([new BundleAnalyzerPlugin()])
}

复制代码

webpack.prod.js

完全なコンポーネントライブラリのパッケージ構成であるwebpack.base.jsから継承された出力ファイルは、すべてのコンポーネントを含むtip-components.min.jsです。モジュラー形式はumdであり、さまざまなインポート方法に適しています。

//webpack.prod.js
var path = require('path')
var webpack = require('webpack')
const merge = require('webpack-merge');
const webpackBaseConfig = require('./webpack.base.js');

const basePath = path.resolve(__dirname, '../')

module.exports = merge(webpackBaseConfig, {
  entry: path.join(basePath, 'src', 'enter.js'),
  output: {
    path: path.resolve(__dirname, '../lib'),
    publicPath: '/lib/',
    filename: 'tip-components.min.js',  // 输出文件名
    library: 'tip-components', // 组件库名称
    libraryTarget: 'umd',  //模块化格式
    umdNamedDefine: true
  },
  externals: {
    vue: {  //将vue依赖 "外部化",不打包进组件库
      root: 'Vue',
      commonjs: 'vue',
      commonjs2: 'vue',
      amd: 'vue'
    }
  },
});
复制代码

ここにパッケージ化されているエントリファイルはsrc/enter.jsです。このエントリファイルが何をするのか、見てみましょう。

enter.js
import dialog from './component/dialog/dialog.js'
import marquee from './component/marquee/main.js'
import toast from './component/toast/toast.js'
//……

const components = {
    dialog,
    marquee,
    toast,
    //……
}

export default components
复制代码

ここでは、すべてのコンポーネントを紹介し、それらをコンポーネントに配置してからエクスポートするだけです。

package.jsonファイルにpackagesコマンドを追加します。

"build": "webpack --config build/webpack.prod.js --progress --hide-modules",
复制代码

実行npm run buildし、コンポーネントライブラリ全体をパッケージ化すれば、完了です。

最后要提的配置文件是webpack.component.js,用于打包单个组件,我们放在下一节。

3. 分块打包配置

一般情况下,我们只需要用组件库中的一两个组件,引入整个组件库显然是不合理的。我们实现按需加载,按需加载的前提就是,我们的组件是支持一个一个单独打包的。

我们先新建一个components.json文件,用于配置哪些组件需要单独打包,以及组件的路径。

//components.json
{
    "marquee": "component/marquee/main.js",
    "toast": "component/toast/toast.js",
    "dialog": "component/dialog/dialog.js",
    //……
}
复制代码

webpack.component.js

继承自webpack.base.js,打包单个组件。

相比webpack.prod.js,我们把entry配置为多个入口,遍历components.json来填充组件的名称和路径信息。output只需要指定一个,用占位符确保输出文件位组件的名称。

var path = require('path')
var webpack = require('webpack')
const merge = require('webpack-merge');
const components = require('./components.json')
const webpackBaseConfig = require('./webpack.base.js');

const basePath = path.resolve(__dirname, '../')
let entries = {}
Object.keys(components).forEach(key => {
  entries[key] = path.join(basePath, 'src', components[key])
})

module.exports = merge(webpackBaseConfig, {
  entry: entries,
  output: {
    path: path.resolve(__dirname, '../lib'),
    publicPath: '/lib/',
    filename: '[name].js',
    chunkFilename: '[id].js',
    library: '[name]', // 指定的就是你使用require时的模块名
    libraryTarget: 'umd',
    umdNamedDefine: true // 会对 UMD 的构建过程中的 AMD 模块进行命名。否则就使用匿名的 define
  },
  externals: {
    vue: {
      root: 'Vue',
      commonjs: 'vue',
      commonjs2: 'vue',
      amd: 'vue'
    }
  }
});
复制代码

我们在package.json文件里面添加一个打包命令。

"build:components": "webpack --config build/webpack.component.js --progress --hide-modules",
复制代码

运行npm run build:components,单独打包组件们,完成!

4. 按需引入组件

既然实现了单个组件的打包,我们当然不会每次都引入整个的组件库,在我们把组件库发布到tnpm后,为了引入单个组件,我们可以这样。

import dom2image from "@tencent/tip-components/lib/dom2image";
复制代码

但路径太长,太麻烦了。

babel-plugin-import

我们可以用babel-plugin-import插件,对路径做一个转换。

安装插件

npm install babel-plugin-import --save-dev
复制代码

在babel.config.js添加配置

//babel.config.js
plugins: [["import", {
	"libraryName": "@tencent/tip-components",
  "libraryDirectory": "lib",  // default: lib
}]]
复制代码

于是,我们可以直接这样用,默认去找到lib文件下的单个组件,美滋滋。

import { dom2image } from "@tencent/tip-components";
复制代码

5. 示例工程

为了方便在开发过程中调试组件,我们可以添加一个入口,用于拉起一个html页面进行调试。这与我们创建一个普通vue页面的操作是一样的,具体配置可以看webpack.demo.js。

我们添加一个打包命令,用webpack-dev-server跑一个示例页面的服务。

"test": "webpack-dev-server --config build/webpack.demo.js --open --hot",
复制代码

webpackテンプレートのフルバージョンではなく、最初にwebpack-simpleを作成したため、パッケージ化された出力jsファイルdist/main.jsをhtmlファイルに積極的に導入する必要があることに注意してください。サンプルページが空白の場合、出力ファイルが正しくインポートされていることを確認してください。

6.ドキュメントの生成

jsdoc

ここでは、jsdocを使用してドキュメントを自動的に生成することを選択します(後で、ここでjsdocを使用して直接生成されたドキュメントは見栄えがよくないことがわかりました。例では、使用法、写真の欠如、GIFデモンストレーションを明確に説明できません。タイムリーに更新されたAPIとして、jsdocで十分です。ただし、ライブラリのユーザーが簡単に開始できるようにするために、コンポーネントのドキュメントを自分で整理することをお勧めします)。

vueコンポーネントがアノテーションをより適切に使用してドキュメントを生成するために、jsdoc-vuejsプラグインも使用します。

構成ファイル。doc.conf.jsonを参照してください。

package.jsonにドキュメントを生成するコマンドを追加します。

"build:doc": "jsdoc -c ./build/doc.conf.json ./src/*"
复制代码

npm run build:docドキュメントを生成できます。

ドキュメント生成の特定のプロセスは、別の記事VueJSドキュメント生成で見ることができます

0.参考記事

vueコンポーネントライブラリを作成する方法

VueJSドキュメントの生成

過去の良い記事

「悪いコードへの別れ」

2022コード仕様のベストプラクティス(Webおよびアプレットの最適な構成の例を含む)

[フロントエンドの調査]悪いコードに別れを告げる!ChainofResponsibilityパターンでネットワークリクエストをカプセル化する

[フロントエンドの調査]不正なコードの第2号に別れを告げます!共有コンポーネントを戦略パターンでカプセル化する

コードライフ

【3年間のフロントエンド開発を考える】要件を効果的に読み取るには?

フロントエンドがピットを踏むための必見ガイド

[フロントエンドの調査]画像読み込みの最適化のベストプラクティス

[フロントエンドの調査]スクリーンショットとポスターを生成するためのモバイル端末H5の調査

【フロントエンド探索】H5はユーザーポジショニングを取得しますか?これを読むのに十分

[フロントエンドの調査]WeChatミニプログラムジャンプの調査-なぜオープンタブが存在するのですか?

[フロントエンドの調査]vConsoleの派手な使用法

おすすめ

転載: juejin.im/post/7082738107237433375