从零开始实现类 antd 分页器(一):搭建项目架构

本文是使用 Typescript 开发类 antd 分页器,并发布 npm 的第一篇,由于最近在业务中使用了 antd 中的 Pagination 开发了相关业务,而本身又对组件的封装由颇有兴趣,因此打算用 ts 来封装一个具备 antd 全部功能的 Pagination。相信你也能轻轻松松的发布一个 npm 组件了。
相关系列文章
从零开始实现类 antd 分页器(一):搭建项目架构
从零开始实现类 antd 分页器(二):分页核心代码
从零开始实现类 antd 分页器(三):发布npm
写做过程当中有些方法的具体实现没有讲到,你们能够自行查看源码。本案例项目仓库:
闲来无事,造个轮子 —— darrell-wheelsjavascript

 

这一节咱们先来说一下,项目基本架构的搭建,咱们使用 Webpack 来做为咱们的项目构建工具,接下来咱们就详细看一下项目的初始目录和详细的依赖安装。css

 

项目初始目录

.
├── 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 开发,安装 typescripttslint
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
复制代码
  • 安装相应的 webpackplugins,下面的 plugins 的做用我就不细说了。
npm install uglifyjs-webpack-plugin html-webpack-plugin clean-webpack-plugin mini-css-extract-plugin -D
复制代码

执行完以上命令,此时 package.json 中包含的依赖信息以下:html

{
  "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 的配置咱们区分:java

  • 开发环境配置文件webpack.dev.config.js
  • 打包发布环境配置文件webpack.prod.config.js

咱们将两个文件中 公共配置 抽出来放在 webpack.base.jsnode

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.jsonscripts,以便咱们能更好的对项目进行 打包运行发布。以下:
...
"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 的事情react

咱们须要使用 babel 把咱们的代码编译成 es5 版本。在项目根目录下建好的 .babelrc文件内补充如下内容:webpack

{
  "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 startnginx

咱们看到在页面中出现了 分页轮子的方法,如图所示:git

在开发过程(使用 webpack-dev-sevrer 启动开发服务)时,并不会实际在 src 目录下生成 bundle.js,打包好的文件是在内存中的,若是你想看 在 example 下面生成了什么的话,你能够作以下改动:github

- "start": "webpack-dev-server --config config/webpack.dev.config.js",
+ "start": "webpack --config config/webpack.dev.config.js",
复制代码

项目初始化就暂时讲到这里,若是还有什么问题,你们能够自行去看一下源码配置。

接下来咱们就能够讲 分页的逻辑 了。

更多的 webpack 配置,能够看笔者最近正在写的 webpack4.0 学习文档

 

小结

这篇文章中咱们讲了一下 分页器 的项目架构的搭建,有了这个骨架以后,咱们就能够开始专心的进行分页器代码的开发。 你们能够移步下一节 从零开始实现类 antd 分页器(二):分页核心代码 查看核心代码的编写过程。

 

参考内容

相关文章
相关标签/搜索