從零開始實現類 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 分頁器(二):分頁核心代碼 查看核心代碼的編寫過程。

 

參考內容

相關文章
相關標籤/搜索