本文是使用
Typescript开发类antd分页器,并发布npm的第一篇,因为最近在业务中使用了antd中的Pagination开发了相关业务,而自己又对组件的封装由很有兴趣,所以打算用ts来封装一个具有antd所有功能的Pagination。相信你也能轻轻松松的发布一个npm组件了。
相关系列文章
从零开始实现类 antd 分页器(一):搭建项目架构
从零开始实现类 antd 分页器(二):分页核心代码
从零开始实现类 antd 分页器(三):发布npm
写作过程中有些方法的具体实现没有讲到,大家可以自行查看源码。本案例项目仓库:
闲来无事,造个轮子 —— darrell-wheels
这一节我们先来讲一下,项目基本架构的搭建,我们使用 Webpack 来作为我们的项目构建工具,接下来我们就详细看一下项目的初始目录和详细的依赖安装。
项目初始目录
.
├── src // 组件源代码目录
├── components // 轮子的目录
├──pangation
├── example // 在这里我放了 分页器的 html dom 片断
├── src // 分页器源代码
└── README.md
├── helpers // 工具函数目录
├── types // typescripe 的接口定义
└── styles // 样式文件目录
├── node_modules // 第三方的依赖
├── config // webpack配置
├── webpack.base.js // 公共配置
├── webpack.dev.config.js // 开发环境配置
└── webpack.prod.config.js // 打包发布环境配置
├── example // 开发时预览代码
└── src // 示例代码目录
├── app.js // 入口 js 文件
└── index.html // 入口 html 文件
├── lib // 组件打包结果目录
├── .babelrc // babel 配置文件
├── .gitignore // git上传时忽略的文件
├── .npmignore // npm 发布时忽略的文件
├── index.html // 项目 html 模版
├── README.md
├── tsconfig.json // ts 的配置文件
├── webpack.dev.config.js // webpack 配置文件
├── package-lock.json
└── package.json // 当前整一个项目的依赖
安装依赖
- 安装
babel编译相关的依赖:
npm i @babel/cli @babel/core @babel/preset-env -D
- 项目采用
webpack做构建,同时使用webpack-dev-server作为本地开发服务器
npm install webpack webpack-cli webpack-dev-server webpack-merge -D
- 项目采用
ts开发,安装typescript和tslint
npm install typescript ts-loader tslint tslint-loader tslint-config-prettier tslint-config-standard -D
- 项目样式使用
less,需要安装less环境,同时安装 相应的编译css的文件
npm install less less-loader style-loader css-loader -D
- 编译图片、字体相应
npm install file-loader url-loader -D
- 安装相应的
webpack的plugins,下面的plugins的作用我就不细说了。
npm install uglifyjs-webpack-plugin html-webpack-plugin clean-webpack-plugin mini-css-extract-plugin -D
执行完以上命令,此时 package.json 中包含的依赖信息如下:
{
"devDependencies": {
"@babel/cli": "^7.8.3",
"@babel/core": "^7.8.3",
"@babel/preset-env": "^7.8.3",
"clean-webpack-plugin": "^0.1.19",
"css-loader": "^1.0.0",
"file-loader": "^2.0.0",
"html-webpack-plugin": "^3.2.0",
"less": "^3.10.3",
"less-loader": "^5.0.0",
"mini-css-extract-plugin": "^0.9.0",
"style-loader": "^0.21.0",
"ts-loader": "^6.2.1",
"tslint": "^5.20.1",
"tslint-config-prettier": "^1.15.0",
"tslint-config-standard": "^8.0.1",
"tslint-loader": "^3.5.4",
"typescript": "^3.7.3",
"uglifyjs-webpack-plugin": "^1.2.7",
"url-loader": "^3.0.0",
"webpack": "^4.16.3",
"webpack-cli": "^3.1.0",
"webpack-dev-server": "^3.1.5",
"webpack-merge": "^4.2.2"
},
"dependencies": {}
}
配置 webpack 和 babel
配置 webpack
对于 webpack 的配置我们区分:
- 开发环境配置文件:
webpack.dev.config.js - 打包发布环境配置文件:
webpack.prod.config.js
我们将两个文件中 公共配置 抽出来放在 webpack.base.js:
const path = require('path');
module.exports = {
resolve: {
extensions: [ '.ts', '.tsx', '.js', '.json']
},
module: {
rules: [
{
test: /\.(ts|tsx)$/,
exclude: /node_modules/,
use: ['ts-loader']
}, {
test: /\.(ts|tsx)?$/,
exclude: /node_modules/,
use: ['tslint-loader'],
}, {
test: /\.less$/,
exclude: /node_modules/,
use: [{
loader: 'style-loader'
}, {
loader: 'css-loader'
}, {
loader: 'less-loader'
}]
}, {
test: /\.(eot|woff2?|woff|ttf|svg|otf)$/,
use: ['file-loader'],
}
]
},
};
- 开发时采用的 webpack 配置写在
webpack.dev.config.js
const path = require('path');
const merge = require('webpack-merge');
const baseConfig = require('./webpack.base.js'); // 引用公共配置
const CleanWebpackPlugin = require('clean-webpack-plugin'); //每次构建清理dist目录
const HtmlWebpackPlugin = require('html-webpack-plugin');
const devConfig = {
mode: 'development', // 开发模式
devtool: 'cheap-module-eval-source-map',
entry: path.join(__dirname, "../example/src/app.js"), // 项目入口,处理资源文件的依赖关系
output: {
path: path.join(__dirname, "../example/src/"),
filename: "bundle.js",
// 使用webpack-dev-sevrer启动开发服务时,
// 并不会实际在`src`目录下生成bundle.js,打包好的文件是在内存中的,但并不影响我们使用。
},
module: {
},
plugins: [
new HtmlWebpackPlugin({
template: path.join(__dirname, '../index.html'),
filename: 'index.html',
}),
new CleanWebpackPlugin(['dist']),
],
devServer: {
contentBase: path.join(__dirname, '../example/src/'),
compress: true,
port: 3001, // 启动端口为 3001 的服务
open: true // 自动打开浏览器
},
};
// 将baseConfig和devConfig合并为一个配置
module.exports = merge(devConfig, baseConfig);
- 打包时采用的 webpack 配置写在
webpack.prod.config.js
const path = require('path');
const merge = require('webpack-merge');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const baseConfig = require('./webpack.base.js'); // 引用公共配置
const prodConfig = {
mode: 'production', // 生产模式
devtool: 'cheap-module-source-map',
entry: path.join(__dirname, "../src/index.ts"), // 项目入口,处理资源文件的依赖关系
output: { // 出口文件
path: path.resolve(__dirname, '../lib/'),
filename: "darrellWheels.min.js",
libraryTarget: 'umd', // 采用通用模块定义
library: 'darrellWhells'
},
plugins: [
new UglifyJsPlugin({
test: /\.js($|\?)/i
}),
],
module: {
rules: [
{
test: /\.less$/,
exclude: /node_modules/,
use: [{
loader: 'style-loader'
}, {
loader: 'css-loader'
}, {
loader: 'less-loader'
}]
},
]
}
};
module.exports = merge(prodConfig, baseConfig); // 将baseConfig和devConfig合并为一个配置
- 最后修改
package.json的scripts,以便我们能更好的对项目进行 打包、运行 与 发布。如下:
...
"scripts": {
"start": "webpack-dev-server --config config/webpack.dev.config.js",
"build": "webpack --config config/webpack.prod.config.js",
"pub": "npm run build && npm publish"
},
...
配置 babel
其实这里我们不需要配置,因为我们使用
ts-loader,他已经帮我们做了babel的事情
我们需要使用 babel 把我们的代码编译成 es5 版本。在项目根目录下建好的 .babelrc文件内补充以下内容:
{
"presets": ["@babel/preset-env"]
}
开发一个最简单的组件
- 首先我们在
src/components/pagination/src下新建一个index.ts,作为my-pagination的入口文件,我们简单的在页面中输出一行字
// src/components/pagination/src
function pagination() {
var dom = document.getElementById('pagination');
var pagination = document.createElement('div');
pagination.innerText = '分页轮子的方法';
dom.append(pagination);
}
export default pagination;
- 我们在
src/index.ts下将轮子导出
// src/index.ts
import Pagination from './components/pagination/src/index';
export { Pagination };
- 我们修改根目录下的 模板
index.html文件:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>分页</title>
</head>
<body>
<div id="pagination"></div>
</body>
</html>
- 接着我们修改
example/src下的app.js文件
import { Pagination } from '../../src/index'; // 引入组件
Pagination(); // 运行
最后我们启动服务,在命令行中输入:npm start;
我们看到在页面中出现了 分页轮子的方法,如图所示:
在开发过程(使用 webpack-dev-sevrer 启动开发服务)时,并不会实际在 src 目录下生成 bundle.js,打包好的文件是在内存中的,如果你想看 在 example 下面生成了什么的话,你可以做如下改动:
- "start": "webpack-dev-server --config config/webpack.dev.config.js",
+ "start": "webpack --config config/webpack.dev.config.js",
项目初始化就暂时讲到这里,如果还有什么问题,大家可以自行去看一下源码配置。
接下来我们就可以讲 分页的逻辑 了。
更多的 webpack 配置,可以看笔者最近正在写的 webpack4.0 学习文档。
小结
这篇文章中我们讲了一下 分页器 的项目架构的搭建,有了这个骨架之后,我们就可以开始专心的进行分页器代码的开发。 大家可以移步下一节 从零开始实现类 antd 分页器(二):分页核心代码 查看核心代码的编写过程。