diff --git a/.changeset/README.md b/.changeset/README.md deleted file mode 100644 index 79d7984f62..0000000000 --- a/.changeset/README.md +++ /dev/null @@ -1,47 +0,0 @@ -# Changesets - -Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works -with multi-package repos, or single-package repos to help you version and publish your code. You can -find the full documentation for it [in our repository](https://github.com/changesets/changesets) - -We have a quick list of common questions to get you started engaging with this project in -[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) - - -## Add A Changeset - -Read the [documentation](https://github.com/changesets/changesets/blob/main/docs/adding-a-changeset.md) for more detail. - -## Publish Snapshot Version - -> NOTE: It is useful for you to release a version to test your package on your current branch. - -Run the following command to publish the snapshot version: - -```bash -$ npm run release:snapshot -``` - -After that, you don't need to commit the change to the branch. - -## Publish Beta Version - -> NOTE: Recommend you to publish a beta version on a new branch(such as `release-beta`) which is checked out from the `release*` branch. - -Run the following command to publish the beta version: - -```bash -$ npm run release:beta -``` - -Then, we need to commit the changes to the branch. - -For more detail, please see this [documentation](https://github.com/changesets/changesets/blob/main/docs/prereleases.md). - -## Publish Latest Version - -GitHub bot will automatically create a PR to update the latest versions for the released package. - -image - -What we need to do is to merge the PR to the `release*` branch. After the `release*` branch was merged to the master branch, the versions will be released automatically. diff --git a/.changeset/config.json b/.changeset/config.json deleted file mode 100644 index 4570eadc8c..0000000000 --- a/.changeset/config.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "$schema": "https://unpkg.com/@changesets/config@2.3.0/schema.json", - "changelog": "@changesets/cli/changelog", - "commit": false, - "fixed": [], - "linked": [], - "access": "restricted", - "baseBranch": "master", - "updateInternalDependencies": "patch", - "ignore": [ - "@examples/*", - "ice-website-v3" - ], - "snapshot": { - "useCalculatedVersion": true, - "prereleaseTemplate": "{tag}-{commit}-{datetime}" - } -} diff --git a/.changeset/dull-steaks-melt.md b/.changeset/dull-steaks-melt.md deleted file mode 100644 index c2235b4d8a..0000000000 --- a/.changeset/dull-steaks-melt.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@ice/runtime': patch ---- - -fix: duplicate css diff --git a/.commitlintrc.js b/.commitlintrc.js deleted file mode 100644 index 54823c7509..0000000000 --- a/.commitlintrc.js +++ /dev/null @@ -1,3 +0,0 @@ -const { getCommitlintConfig } = require('@applint/spec'); - -module.exports = getCommitlintConfig('common'); diff --git a/.editorconfig b/.editorconfig index 06cc6647e2..22ef5ace54 100644 --- a/.editorconfig +++ b/.editorconfig @@ -7,7 +7,6 @@ indent_size = 2 charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true -quote_type=single [*.md] trim_trailing_whitespace = false @@ -15,7 +14,3 @@ trim_trailing_whitespace = false [makefile] indent_style = tab indent_size = 4 - -[*.rs] -indent_style = space -indent_size = 4 \ No newline at end of file diff --git a/.eslintignore b/.eslintignore index b95cb05b89..7dbcda88e1 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,28 +1,20 @@ # 忽略目录 build/ -fixtures/ +tests/ +demo/ +react-materials/layouts/**/lib/ +react-materials/blocks/**/lib/ node_modules/ -dist/ -out/ -compiled/ -public/ +scripts/ # node 覆盖率文件 coverage/ -# 忽略测试文件 -/packages/*/lib/ -/packages/*/esm/ -/packages/*/es2017/ -/packages/*/es2021/ -**/tests/libs/*.js - -# 忽略第三方包 -/vendor/loader.js -override/ - # 忽略文件 **/*-min.js **/*.min.js -workspace/ +# templorarily ignore tools +tools/ + +**/templates/** diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000000..4b9a90acce --- /dev/null +++ b/.eslintrc @@ -0,0 +1,60 @@ +{ + "root": true, + "parser": "babel-eslint", + "extends": "eslint-config-airbnb", + "parserOptions": { + "ecmaVersion": 6, + "ecmaFeatures": { + "jsx": true, + "experimentalObjectRestSpread": true + } + }, + "env": { + "browser": true, + "mocha": true, + "node": true, + "commonjs": true + }, + "plugins": ["react", "babel"], + "rules": { + "arrow-parens": [2, "always"], + "no-console": 0, + "no-use-before-define": 0, + "react/forbid-prop-types": 0, + "jsx-a11y/label-has-for": 0, + "jsx-a11y/no-static-element-interactions": 0, + "jsx-a11y/anchor-has-content": 0, + "jsx-a11y/click-events-have-key-events": 0, + "jsx-a11y/anchor-is-valid": 0, + "react/no-array-index-key": 0, + "func-names": 0, + "arrow-body-style": 0, + "react/sort-comp": 0, + "react/prop-types": 0, + "react/jsx-first-prop-new-line": 0, + "react/jsx-filename-extension": [ + 1, + { + "extensions": [".js", ".jsx"] + } + ], + "import/extensions": 0, + "import/no-unresolved": 0, + "import/no-extraneous-dependencies": 0, + "prefer-destructuring": 0, + "no-param-reassign": 0, + "no-return-assign": 0, + "max-len": 0, + "consistent-return": 0, + "no-redeclare": 0, + "react/require-extension": 0, + "react/no-danger": 0, + "comma-dangle": ["error", "always-multiline"], + "function-paren-newline": 0, + "object-curly-newline": 0, + "no-restricted-globals": 0, + "react/prefer-stateless-function": 0, + "react/jsx-no-bind": 0, + "no-plusplus": 0 + } +} diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index e7cf50e623..0000000000 --- a/.eslintrc.js +++ /dev/null @@ -1,54 +0,0 @@ -const { getESLintConfig } = require('@applint/spec'); - -const commonRules = { - 'react/jsx-filename-extension': 0, - 'react/no-unknown-property': 0, - 'no-underscore-dangle': 0, - 'class-methods-use-this': 0, - 'no-param-reassign': 0, - 'no-console': 0, - 'comma-dangle': 0, - 'prefer-object-spread': 0, - 'import/named': 0, - indent: 0, - 'react/react-in-jsx-scope': 0, - 'jsx-a11y/html-has-lang': 0, - 'react/static-property-placement': 0, - 'no-multiple-empty-lines': 1, - 'react/jsx-no-bind': 0, - 'import/order': 1, - 'no-multi-assign': 0, -}; - -module.exports = getESLintConfig('react-ts', { - rules: { - ...commonRules, - '@typescript-eslint/ban-types': 0, - '@typescript-eslint/ban-ts-comment': 0, - '@typescript-eslint/no-explicit-any': 0, - '@typescript-eslint/interface-name-prefix': 0, - '@typescript-eslint/explicit-function-return-type': 0, - '@typescript-eslint/no-var-requires': 0, - '@typescript-eslint/explicit-module-boundary-types': 0, - '@typescript-eslint/prefer-for-of': 0, - 'id-length': 0, - 'no-use-before-define': 0, - 'no-unused-vars': 0, - '@typescript-eslint/no-unused-vars': ['warn', { - varsIgnorePattern: '[iI]gnored|createElement', - }], - '@typescript-eslint/ban-ts-ignore': 0, - '@typescript-eslint/no-confusing-void-expression': 0, - '@typescript-eslint/promise-function-async': 0, - '@typescript-eslint/no-unnecessary-type-assertion': 0, - '@typescript-eslint/non-nullable-type-assertion-style': 0, - '@typescript-eslint/no-unnecessary-type-arguments': 0, - '@typescript-eslint/await-thenable': 0, - '@typescript-eslint/prefer-nullish-coalescing': 0, - '@typescript-eslint/consistent-type-imports': 2, - }, - parserOptions: { - project: [], - createDefaultProgram: false, - }, -}); \ No newline at end of file diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index b5306e581f..f4aeec3109 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -2,68 +2,32 @@ Hi! I’m really excited that you are interested in contributing to ICE. Before submitting your contribution though, please make sure to take a moment and read through the following guidelines. -- [Setup Environment](#setup-environment) -- [Run Examples](#run-examples) -- [Publish Packages](publish-packages) -- [Pull Request Guidelines](#pull-request-guidelines) - [Issue Reporting Guidelines](#issue-reporting-guidelines) -- [Git Commit Specific](#git-commit-specific) - -## Setup Environment - -clone repo and initialize the setup environment: - -```bash -# 1. clone and setup -$ git clone git@github.com:alibaba/ice.git -$ cd ice && npm run setup - -# 2. watch packages -$ npm run watch -``` - -## Run Examples - -We provide a lot of examples, you can run the examples: - -```bash -$ cd examples/basic-project -$ npm start -``` +- [Pull Request Guidelines](#pull-request-guidelines) +- [Git Commit Specific](./GIT_COMMIT_SPECIFIC.md) -## Publish Packages -When you need to release, you can execute the command: +## Issue Reporting Guidelines -```bash -$ npm run publish -# 1. ✔️ ✔️ ✔️ Checking the working tree status... -# 2. 📦 📦 📦 Building packages... -# 3. ⚡ ⚡ ⚡ Update package version automatically... -# 4. 🚀 🚀 🚀 Start publishing... -# 5. 🔖 🔖 🔖 Commit & Create tag'... -# 6. 💡 💡 💡 Start syncing... -``` +- The issue list of this repo is **exclusively** for bug reports and feature requests. Non-conforming issues will be closed immediately. -> DO NOT manually execute the publish command, using Github Actions provided. + - For simple beginner questions, you can get quick answers from -## Rollback Packages + - For more complicated questions, you can use Google or StackOverflow. Make sure to provide enough information when asking your questions - this makes it easier for others to help you! -When a serious bug occurs in the production environment, you can backtrack the package version: +- Try to search for your issue, it may have already been answered or even fixed in the development branch. -```bash -# rollback packages -$ npm run rollback +- It is **required** that you clearly describe the steps necessary to reproduce the issue you are running into. Issues with no clear repro steps will not be triaged. If an issue labeled "need repro" receives no further input from the issue author for more than 5 days, it will be closed. -# sync packages -$ npm run sync -``` +- For bugs that involves build setups, you can create a reproduction repository with steps in the README. +- If your issue is resolved but still open, don’t hesitate to close it. In case you found a solution by yourself, it could be helpful to explain how you fixed it. ## Pull Request Guidelines - Only code that's ready for release should be committed to the master branch. All development should be done in dedicated branches. - Checkout a **new** topic branch from master branch, and merge back against master branch. +- Work in the `src` folder and **DO NOT** checkin `lib` or `dist` in the commits. - Make sure `npm test` passes. - If adding new feature: - Add accompanying test case. @@ -73,15 +37,6 @@ $ npm run sync - Provide detailed description of the bug in the PR. Live demo preferred. - Add appropriate test coverage if applicable. -## Issue Reporting Guidelines - -- The issue list of this repo is **exclusively** for bug reports and feature requests. Non-conforming issues will be closed immediately. - - For simple beginner questions, you can get quick answers from - - For more complicated questions, you can use Google or StackOverflow. Make sure to provide enough information when asking your questions - this makes it easier for others to help you! -- Try to search for your issue, it may have already been answered or even fixed in the development branch. -- It is **required** that you clearly describe the steps necessary to reproduce the issue you are running into. Issues with no clear repro steps will not be triaged. If an issue labeled "need repro" receives no further input from the issue author for more than 5 days, it will be closed. -- For bugs that involves build setups, you can create a reproduction repository with steps in the README. -- If your issue is resolved but still open, don’t hesitate to close it. In case you found a solution by yourself, it could be helpful to explain how you fixed it. ## Git Commit Specific diff --git a/.github/GIT_COMMIT_SPECIFIC.md b/.github/GIT_COMMIT_SPECIFIC.md index b5b6d10e8d..ae2b9398fe 100644 --- a/.github/GIT_COMMIT_SPECIFIC.md +++ b/.github/GIT_COMMIT_SPECIFIC.md @@ -3,13 +3,14 @@ **Proposed format of the commit message** ``` -: +(): ``` All lines are wrapped at 100 characters ! + **Allowed ``** - feat (A new feature) @@ -23,15 +24,18 @@ All lines are wrapped at 100 characters ! - ci (Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs)) - chore (Other changes that don't modify src or test files) - revert (Reverts a previous commit) -- release (Relase version) +**Allowed ``** +Scope could be anything specifying place of the commit change. -**Breaking changes** +For example $location, $browser, compiler, scope, ng:href, etc... + +**Breaking changes** All breaking changes have to be mentioned in message body, on separated line: +​ _Breaks removed $browser.setUrl() method (use $browser.url(http://github.com/newUrl))_ +​ _Breaks ng: repeat option is no longer supported on selects (use ng:options)_ -​ _Breaks removed $browser.setUrl() method (use $browser.url(http://github.com/newUrl))_ -​ _Breaks ng: repeat option is no longer supported on selects (use ng:options)_ **Message body** diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 0000000000..ee90e83a04 --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,13 @@ +## 环境信息 + +- 操作系统: +- Iceworks 版本: + +## 问题描述 + + + +## 错误信息 + + + diff --git a/.github/ISSUE_TEMPLATE/Bug_Report.yml b/.github/ISSUE_TEMPLATE/Bug_Report.yml deleted file mode 100644 index a92f1e76f5..0000000000 --- a/.github/ISSUE_TEMPLATE/Bug_Report.yml +++ /dev/null @@ -1,47 +0,0 @@ -name: Bug Report -description: Report ice.js, documents and other issues -labels: bug -body: - - type: textarea - id: description - attributes: - label: Describe the bug - description: | - If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem. - 清晰的描述遇到的问题,并建议附上错误截图。 - validations: - required: true - - type: textarea - id: expected-behavior - attributes: - label: Expected behavior - description: | - A clear and concise description of what you expect to happen. - 描述您希望的正常表现。 - validations: - required: true - - type: textarea - id: actual-behavior - attributes: - label: Actual behavior - description: | - A clear and concise description of actual behavior. - 请清晰、简洁地描述您的实际表现。 - validations: - required: false - - type: input - id: version - attributes: - label: Version of ice.js - validations: - required: true - - type: textarea - id: build-config - attributes: - label: Content of build.json or ice.config.mts - render: TypeScript - - type: textarea - id: addition - attributes: - label: Additional context - placeholder: Add any other context about the problem here. 添加其它关于此问题的描述。 diff --git a/.github/ISSUE_TEMPLATE/RFC_Discussion.yml b/.github/ISSUE_TEMPLATE/RFC_Discussion.yml deleted file mode 100644 index 88d79140b7..0000000000 --- a/.github/ISSUE_TEMPLATE/RFC_Discussion.yml +++ /dev/null @@ -1,34 +0,0 @@ -name: RFC Discussion -description: To submit a feature request or a proposal, follow the RFC process. -labels: rfc -body: - - type: textarea - id: summary - attributes: - label: Summary | 概述 - placeholder: Optional, brief explanation of the feature. - - type: textarea - id: motivation - attributes: - label: Motivation | 背景 - placeholder: Why are we doing this? What use cases does it support? What is the expected outcome? - validations: - required: true - - type: textarea - id: example - attributes: - label: Usage example | 使用示例 - placeholder: If the proposal involves a new or changed API, include a basic code example. Omit this section if it's not applicable. - - type: textarea - id: design - attributes: - label: Detailed design | 方案设计 - placeholder: | - This is the bulk of the RFC. Explain the design in enough detail for somebody familiar with React to understand, and for somebody familiar with the implementation to implement. This should get into specifics and corner-cases, and include examples of how the feature is used. Any new terminology should be defined here. - validations: - required: true - - type: textarea - id: addition - attributes: - label: Additional context | 额外信息 - placeholder: What parts of the design are still to be done? Add any other context about this feature here. diff --git a/.github/workflows/canary.yml b/.github/workflows/canary.yml deleted file mode 100644 index 29e0a0651b..0000000000 --- a/.github/workflows/canary.yml +++ /dev/null @@ -1,55 +0,0 @@ -name: Publish canary - -on: - push: - branches: - - release/** - -jobs: - check_changeset: - name: Check Changeset exists - outputs: - status: ${{ steps.check.outcome }} - runs-on: ubuntu-latest - - steps: - - name: Checkout Branch - uses: actions/checkout@v4 - - - name: Check - id: check - continue-on-error: true - run: test "$(ls -1 .changeset | wc -l)" -gt "2" - - canary: - name: Publish Canary - runs-on: ubuntu-latest - needs: check_changeset - if: needs.check_changeset.outputs.status == 'success' - - strategy: - matrix: - node-version: [18] - - steps: - - name: Checkout Branch - uses: actions/checkout@v4 - - - name: Install pnpm - uses: pnpm/action-setup@v4 - - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4 - with: - node-version: ${{ matrix.node-version }} - cache: 'pnpm' - - - name: Setup - run: pnpm run setup - - - name: Config npm - run: echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > .npmrc - env: - NPM_TOKEN: ${{ secrets.NPM_TOKEN }} - - - run: pnpm run release:snapshot diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml deleted file mode 100644 index cc91aa6007..0000000000 --- a/.github/workflows/ci.yml +++ /dev/null @@ -1,49 +0,0 @@ -name: CI - -env: - NODE_OPTIONS: --max-old-space-size=6144 - -on: [push] - -jobs: - build: - runs-on: ${{ matrix.os }} - strategy: - matrix: - node-version: [16.x, 18.x] - os: [ubuntu-latest, windows-latest] - fail-fast: false - steps: - - name: Checkout Branch - uses: actions/checkout@v3 - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v3 - with: - node-version: ${{ matrix.node-version }} - registry-url: https://registry.npmjs.org/ - - name: Install pnpm - uses: pnpm/action-setup@v4 - with: - run_install: false - - name: Get pnpm store directory - id: pnpm-cache - run: | - echo "pnpm_cache_dir=$(pnpm store path)" >> "$GITHUB_OUTPUT" - - uses: actions/cache@v3 - name: Setup pnpm cache - with: - path: | - ${{ steps.pnpm-cache.outputs.pnpm_cache_dir }} - .cache - key: ${{ runner.os }}-pnpm-store-node-${{ matrix.node-version }}-${{ hashFiles('**/pnpm-lock.yaml') }} - restore-keys: | - ${{ runner.os }}-pnpm-store-node-${{ matrix.node-version }} - - run: npm run setup - - run: npm run dependency:check - - run: npm run lint - - run: npm run test - env: - TEST: true - CI: true - ACCESS_KEY_ID: ${{ secrets.ACCESS_KEY_ID }} - ACCESS_KEY_SECRET: ${{ secrets.ACCESS_KEY_SECRET }} diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml deleted file mode 100644 index 6ed68113bf..0000000000 --- a/.github/workflows/coverage.yml +++ /dev/null @@ -1,66 +0,0 @@ -name: Coverage - -env: - NODE_OPTIONS: --max-old-space-size=6144 - -on: - push: - branches: - - master - paths-ignore: - - 'examples/**' - - 'website/**' - - '**/*.md' - pull_request: - types: - - 'opened' - - 'synchronize' - workflow_dispatch: - -concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - coverage: - permissions: - checks: write - pull-requests: write - contents: read - runs-on: ubuntu-latest - strategy: - matrix: - node-version: [16.x] - - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v3 - with: - node-version: ${{ matrix.node-version }} - registry-url: https://registry.npmjs.org/ - - name: Install pnpm - uses: pnpm/action-setup@v4 - with: - run_install: false - - name: Get pnpm store directory - id: pnpm-cache - run: | - echo "pnpm_cache_dir=$(pnpm store path)" >> "$GITHUB_OUTPUT" - - uses: actions/cache@v3 - name: Setup pnpm cache - with: - path: | - ${{ steps.pnpm-cache.outputs.pnpm_cache_dir }} - .cache - key: ${{ runner.os }}-pnpm-store-node-${{ matrix.node-version }}-${{ hashFiles('**/pnpm-lock.yaml') }} - restore-keys: | - ${{ runner.os }}-pnpm-store-node-${{ matrix.node-version }} - - run: npm run setup - - run: npm run cov - - name: Upload coverage to Codecov - uses: codecov/codecov-action@v3 - env: - CI: true diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index 9f2c7e8dc5..0000000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,48 +0,0 @@ -name: Release - -on: - push: - branches: - - master - -jobs: - release: - name: Release - runs-on: ubuntu-latest - - strategy: - matrix: - node-version: [16] - - steps: - - name: Checkout Branch - uses: actions/checkout@v3 - - - name: Install pnpm - uses: pnpm/action-setup@v4 - - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v3 - with: - node-version: ${{ matrix.node-version }} - cache: 'pnpm' - - - name: Setup - run: pnpm run setup - - - name: Setup git user - run: pnpm run setup-git - - - name: Publish to npm - id: changesets - uses: changesets/action@v1 - with: - version: pnpm run version - commit: 'chore: update versions' - title: 'chore: update versions' - publish: pnpm release - createGithubReleases: false - setupGitUser: false - env: - GITHUB_TOKEN: ${{ secrets.PERSONAL_GITHUB_TOKEN }} - NPM_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.github/workflows/version.yml b/.github/workflows/version.yml deleted file mode 100644 index 640402c4c3..0000000000 --- a/.github/workflows/version.yml +++ /dev/null @@ -1,44 +0,0 @@ -name: Version - -on: - push: - branches: - - release/next - -jobs: - version: - name: Version - runs-on: ubuntu-latest - - strategy: - matrix: - node-version: [16] - - steps: - - name: Checkout Branch - uses: actions/checkout@v3 - - - name: Install pnpm - uses: pnpm/action-setup@v4 - - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v3 - with: - node-version: ${{ matrix.node-version }} - cache: 'pnpm' - - - name: Install Dependencies - run: pnpm install - - - name: Setup git user - run: pnpm run setup-git - - - name: Create Release Pull Request - uses: changesets/action@v1 - with: - version: pnpm run version - commit: 'chore: update versions' - title: 'chore: update versions' - setupGitUser: false - env: - GITHUB_TOKEN: ${{ secrets.PERSONAL_GITHUB_TOKEN }} diff --git a/.github/workflows/website.yml b/.github/workflows/website.yml deleted file mode 100644 index 1c86fd4d55..0000000000 --- a/.github/workflows/website.yml +++ /dev/null @@ -1,41 +0,0 @@ -name: Build Website -on: - push: - paths: - - 'website/**' - branches: - - master - workflow_dispatch: - -# 任务 -jobs: - build-and-deploy: - # 服务器环境:最新版 Ubuntu - runs-on: ubuntu-latest - steps: - # 拉取代码 - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - - name: Install pnpm - uses: pnpm/action-setup@v4 - - - name: Use Node.js 16.x - uses: actions/setup-node@v3 - with: - node-version: 16.x - cache: 'pnpm' - - - run: pnpm install --filter=./website - - - run: cd website && pnpm build - - # 部署到 GitHub Pages - - name: Deploy - uses: JamesIves/github-pages-deploy-action@4.1.0 - if: github.ref == 'refs/heads/master' - with: - BRANCH: gh-pages - FOLDER: website/build - clean-exclude: ice.png diff --git a/.gitignore b/.gitignore index 16b66d940f..77c7598919 100644 --- a/.gitignore +++ b/.gitignore @@ -1,59 +1,16 @@ -# https://github.com/github/gitignore/blob/master/Node.gitignore -# Dependencies node_modules -jspm_packages - -# Only keep yarn.lock in the root -package-lock.json -*/**/yarn.lock - -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -lerna-debug.log* - -# Coverage directory used by tools like istanbul -coverage -*.lcov - -# Others -.npm -.eslintcache -.idea .DS_Store +lerna-debug.log +npm-debug.log +mochawesome-report .happypack -.vscode -.tmp -.cache -*.swp -*.dia~ -*.temp.json -*.swc - -# yalc -.yalc -yalc.lock - -# Packages -packages/*/lib/ -packages/*/esm/ -packages/*/es2017/ - -# temp folder .ice -examples/*/.ice -examples/*/.swc - +package-lock.json +*/blocks/**/lib/ +*/layouts/**/lib/ +.eslintcache +databases build -dist -.history -compiled - -# website -.docusaurus -.cache-loader +.vscode/ +tools/ice-scripts/lib/ICE_CA -*.local -.fleet/ +npmrc diff --git a/.husky/commit-msg b/.husky/commit-msg deleted file mode 100755 index 5a8500090b..0000000000 --- a/.husky/commit-msg +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh -. "$(dirname "$0")/_/husky.sh" - -npx --no -- commitlint --edit $1 diff --git a/.husky/pre-commit b/.husky/pre-commit deleted file mode 100755 index 36af219892..0000000000 --- a/.husky/pre-commit +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh -. "$(dirname "$0")/_/husky.sh" - -npx lint-staged diff --git a/.npmrc b/.npmrc deleted file mode 100644 index 741a833fe6..0000000000 --- a/.npmrc +++ /dev/null @@ -1,2 +0,0 @@ -strict-peer-dependencies=false -registry=https://registry.npmjs.org/ diff --git a/.prettierignore b/.prettierignore index 6804be2e85..ec6d3cdd7f 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,9 +1 @@ -node_modules -.ice -dist -*.d.ts -*.js -fixtures -*.md -*.yaml -*.less \ No newline at end of file +package.json diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000000..ee34d3b1a2 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,6 @@ +{ + "trailingComma": "es5", + "singleQuote": true, + "bracketSpacing": true, + "arrowParens": "always" +} diff --git a/.prettierrc.js b/.prettierrc.js deleted file mode 100644 index a0a7f3a25f..0000000000 --- a/.prettierrc.js +++ /dev/null @@ -1,2 +0,0 @@ -const { getPrettierConfig } = require('@applint/spec'); -module.exports = getPrettierConfig('common'); \ No newline at end of file diff --git a/.puppeteerrc.cjs b/.puppeteerrc.cjs deleted file mode 100644 index 3d02138cca..0000000000 --- a/.puppeteerrc.cjs +++ /dev/null @@ -1,9 +0,0 @@ -const { join } = require('path'); - -/** - * @type {import("puppeteer").Configuration} - */ -module.exports = { - // Changes the cache location for Puppeteer. - cacheDirectory: join(__dirname, '.cache', 'puppeteer'), -}; \ No newline at end of file diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000..6890d3d48b --- /dev/null +++ b/.travis.yml @@ -0,0 +1,15 @@ +sudo: required +language: node_js +node_js: +- '8' +script: +- npm run lint:nofix + +deploy: + provider: script + skip_cleanup: true # 避免清空已安装的依赖 + script: node ./scripts/deploy.js && npm run generate && npm run sync + on: + all_branches: true # 仅在 master | pre-depoly 分支进行 deploy + repo: alibaba/ice + condition: $TRAVIS_BRANCH =~ ^master|pre-depoly$ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index bd968657b6..0000000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,100 +0,0 @@ -# 参与贡献 - -## 环境准备 - -1. 保证 Node.js 版本是 Node.js 14 以上。推荐安装 Node.js 16+ 版本,会大大提升本地调试速度 -2. ice.js 仓库是 `monorepo`,并使用 `pnpm workspace`。因此需要安装 [pnpm](https://pnpm.io/) 包管理工具 -3. 在项目根目录下执行 `pnpm run setup` 后会安装依赖和编译代码 - -> 如果在安装 puppeteer 的时候过慢,可以参考此 [issue](https://github.com/puppeteer/puppeteer/issues/6833#issuecomment-863488626) 进行配置 chromium 缓存。 - -## 目录说明 - -```markdown -ice-next -├── examples # 存档各种示例代码 -├── packages # 存放 npm 包 -| ├── bundles # 依赖预编译,锁定框架三方依赖版本,框架中的依赖需要从此包导入模块 -| ├── ice # 工程代码,包括创建 service、构建任务、Webpack 和 esbuild 的打包编译逻辑等 -| ├── plugin-auth # Auth 插件 -| ├── route-manifest # 根据约定式路由生成路由配置 -| ├── runtime # 运行时代码,包括 Client/Server 入口、Document、路由组件等 -| ├── types # 公共 TS 依赖 -| └── webpack-config # 存放 Webpack 默认的配置项 -├── scripts # 执行脚本 -├── tests # 测试用例 -| ├── integration -| └── utils -└── website # ice.js 官方文档 -``` - -补充说明: - -1. `packages` 目录下以 `plugin-xxx` 命名的都是插件包,插件的开发规范可以参考[文档]() -2. `packages/types` 是用于存放公共的 TS 类型声明,以在其他 `package` 中进行复用 - -## 调试 - -### 启动 watch 命令 - -此命令用于监听 `packages` 目录下代码变更,并增量编译代码。 - -```bash -pnpm watch -``` - -### 跑 example - -`examples` 目录下存放了各种用于测试的 demo,并且自动 Link 到 `packages` 目录下的代码。只需执行以下命令即可开始调试: - -```bash -# 进入某个 example -$ cd examples/basic-project -# 调试 example -$ pnpm start -``` - -`packages` 目录下的 `npm` 包在进行代码编译时会生成 `SourceMap`,结合 IDE 可以很方便进行断点调试。以 VS Code 为例: - -1. 选择 `JavaScript Debug Terminal` 进入 Debug 模式: -![image](https://user-images.githubusercontent.com/44047106/172011203-8b3b4016-8f7b-4743-bbef-30672ab04b03.png) - -2. 进入某个 `example` 目录并执行 `pnpm start` 开始调试 - -3. 在某一行设置一个断点,当代码执行到此行时,将会停止执行并可查看各个变量的值 -![image](https://user-images.githubusercontent.com/44047106/172013483-028d0fa8-8634-46fe-bbb6-1b28b39b8ce1.png) - -## 测试 - -ice.js 使用 [vitest](https://vitest.dev/) 进行单元测试和集成测试。执行以下命令可快速运行项目中的测试用例: - -```bash -# 执行一次测试并生成代码覆盖率 -$ pnpm test -# 启用 Test Watch 模式 -$ pnpm test:watch -# 只跑部分测试用例 -$ pnpm test basic-project.test.ts -``` - -## 文档 - -ice.js 的文档使用了 [docusaurus](https://docusaurus.io/) 进行搭建。执行以下命令即可开始文档的开发: - -```bash -# 进入到 website 目录 -$ cd websites -# 安装依赖 -$ yarn install -# 本地预览 -$ yarn start -``` - -## 发布 - -```bash -# 发布 alpha 版本 -$ pnpm publish:alpha -# 发布 beta 版本 -$ pnpm publish:beta -``` diff --git a/README.md b/README.md index e80eac8d2e..6002f3bd61 100644 --- a/README.md +++ b/README.md @@ -1,62 +1,52 @@ -# ice.js -

- Downloads - Version - GitHub license - PRs Welcome - Gitter - Leaderboard - Open with OpenSumi + +    飞冰 +

+

让前端开发简单而友好

-A universal framework based on React.js, [📚 Docs](https://ice.work/). - -## Features +

+ +   +   +

-- 🐒 **Zero Config**: Out of the box support for ES6+, TypeScript, Less, Sass, CSS Modules,etc -- 🐯 **Practice**: Practice about file-system routing, state Management, request, etc -- 🦁 **Hybrid**: pre-render pages at build time (SSG) or request time (SSR) for default -- 🐌 **Plugin system**: The plugin system provides rich features and allow the community to build reusable solutions -- 🐂 **Multi-End**: Support both web, miniapp and Weex +--- -## Quick start + + 飞冰 + -We recommend creating a new ice.js app using create-ice, which sets up everything automatically for you. To create a project, run: +:zap: **[`海量高质量物料`](https://alibaba.github.io/ice/block)** 物料丰富:组件、区块、布局、模版,场景化分类,覆盖面广,官方与社区共同维护;专业视觉设计,`每周持续有新增`,满足日常开发之所需。 -```bash -$ npm init ice ice-app --template @ice/lite-scaffold -``` +:dart: **[`ICEWORKS 桌面工具`](https://alibaba.github.io/ice/iceworks)** 极速上手,全链路工程支持:多项目管理、页面路由管理、包依赖管理、零配置本地构建、代理配置、一键发布等,`效率提升 100%`;插件化的工作台,可自定义插件启用,让前端开发得心应手。 -`npm init ` is available in npm 6+ +:art: **[`ICE DESIGN 设计语言`](https://alibaba.github.io/ice/design.html)** 传统平台界面的设计语言存在着的一些不足,比如色彩单一,大量线条的使用,分割化明显。将这些不足归类一下就是界面单调、雷同性明显、缺少惊喜。我们认为新的平台类视觉风格可以打破这些束缚,尝试一些新的探索,启发传统的设计认知,因此结合当下设计趋势,构思了平台产品设计语言 ICE DESIGN。 -Start local server to launch project: +## 开始使用 -```bash -$ cd ice-app -$ npm install -$ npm run start # running on http://localhost:3000. -``` +下载 [`ICEWORKS`](https://alibaba.github.io/ice/iceworks) 后创建或导入项目,详细步骤请浏览 [`快速上手指南`](https://alibaba.github.io/ice/docs/iceworks)。 -It's as simple as that! +## 参与物料建设 -## Contributing +参考[`物料贡献指南`](https://alibaba.github.io/ice/docs/materials/how-to-contribute)开发完成后 `PR` 到官方仓库。 -Please see our [CONTRIBUTING.md](/.github/CONTRIBUTING.md) +## 浏览器兼容性 -## Contributors +![Chrome](https://raw.github.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png) | ![Firefox](https://raw.github.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png) | ![Edge](https://raw.github.com/alrra/browser-logos/master/src/edge/edge_48x48.png) | ![IE](https://raw.github.com/alrra/browser-logos/master/src/archive/internet-explorer_9-11/internet-explorer_9-11_48x48.png) | ![Safari](https://raw.github.com/alrra/browser-logos/master/src/safari/safari_48x48.png) | ![Opera](https://raw.github.com/alrra/browser-logos/master/src/opera/opera_48x48.png) | ![UC](https://raw.github.com/alrra/browser-logos/master/src/uc/uc_48x48.png) +:---: | :---: | :---: | :---: | :---: | :---: | :---: + ✔ | ✔ | ✔ | 10+ ✔ | ✔ | ✔ | ✔ -Contributors can contact us to join the Contributor Group. +## README 徽章 - - Contribution Leaderboard - +如果你的项目正在使用飞冰,可以将飞冰徽章 [![ice](https://img.shields.io/badge/developing%20with-ICE-2077ff.svg)](https://github.com/alibaba/ice) 添加到你的 README 中: -## Community +``` +[![ice](https://img.shields.io/badge/developing%20with-ICE-2077ff.svg)](https://github.com/alibaba/ice) +``` -- [Issues](https://github.com/alibaba/ice/issues) -- [Gitter](https://gitter.im/alibaba/ice) +## 加入社区 -## LICENSE +扫码加入即刻交流与反馈: -[MIT](https://github.com/alibaba/ice/blob/master/LICENSE) +Join the chat at dingtalk diff --git a/codecov.yml b/codecov.yml deleted file mode 100644 index b20a0d54e6..0000000000 --- a/codecov.yml +++ /dev/null @@ -1,9 +0,0 @@ -coverage: - status: - patch: off - project: - default: - threshold: 5% - -github_checks: - annotations: false \ No newline at end of file diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000000..986a0ad728 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,33 @@ +> 在修改文档之前,请先阅读此文章 + +### 目录结构 + +``` +- foo.md 文档内容, 可以有文件夹嵌套 +- yoo.md +``` + +### 文档结构 + +```markdown +--- +title: 文档标题(必须有) +order: 可选, 文档顺序, 数字越小越在前面, 否则按照字母序 +hide: 可选, 布尔值, 是否隐藏文档 +category: 可选, 字符串, 一级分类 +cover: 可选, 建议有, 封面图 +--- + +markdown 格式的文档内容 +``` + +### 词汇表述 + +请注意大小写和复数形式 + +* `ICE`: 品牌名, 中文称之为 `飞冰` +* `Iceworks`: 配套 GUI 软件 +* `物料 - marterial`: 包含区块, 布局, 模板和组件 +* `区块 - block`: 复用的最小代码片段 +* `布局 - layout`: 为 ICE 提供整体布局方案的代码 +* `模板 - scaffold`: 整站示例, 脚手架 diff --git a/docs/about.md b/docs/about.md new file mode 100644 index 0000000000..a18e6d4808 --- /dev/null +++ b/docs/about.md @@ -0,0 +1,40 @@ +--- +title: 关于飞冰 +order: 1 +cover: https://gw.alicdn.com/tfs/TB1vBRYaVOWBuNjy0FiXXXFxVXa-2558-1306.jpg +--- + +## 目标和愿景 + +飞冰是一套基于 React 的中后台应用解决方案,在阿里巴巴内部,已经有 270 多个来自几乎所有 BU 的项目在使用。经过 2 年的发展,飞冰已经是中后台 2.0 体系,这个阶段中我们的目标是赋能企业、组织搭建自己的中后台体系。飞冰包含了一条从设计端到开发端的完整链路,帮助我们的用户快速搭建属于自己的中后台应用。 + +我们希望中后台应用的开发能变得更高效。面向**设计者**端,我们提供了 ICE Design 设计语言,来给我们的 UI 界面提供专业的视觉指导。面向**开发者**端,我们提供了 Iceworks 工具,这是一个图形化界面的开发平台,它承载了飞冰的物料体系和开发体验,获取更多信息您可以立即[点击这里](#/iceworks)下载体验。同时,我们还提供了独有的**服务体系**,在物料与工具这一基础之上进行服务的配套。我们将构建一个面向开发者的服务体系。针对每一个使用飞冰的企业或个人,我们会安排专人客服进行一对一的对接,一旦有问题可以随时找到我们,第一时间帮助解决问题。 + +## 初心 + +在整个阿里体系内,面向卖家、运营小二以及达人有数不尽的后台,并且这些后台一直在持续不断的增长着,但是随着时间的推移,这些项目或多或少的存在着以下这些问题: + +* 每个后台相互独立,同类功能也需要重复开发,前期开发成本较高 +* 技术方案差异大,人员变动后维护成本非常高 +* 视觉质量参差不齐,使用效率大打折扣 +* ... + +飞冰就是为了解决这些问题而诞生。飞冰由淘宝前端团队发起,与淘宝 UED 及后端开发同学共同打造,旨在「提高中后台系统的开发效率」。 + +## 物料体系 + +在飞冰中,组件、区块、布局、模板等统称为物料,由飞冰团队维护,在内部有一套完整的开发规范和工具,目前也正在逐步对外开放中;基于此,你可以参与共建飞冰,也可以自建私有的物料体系。 + +* 组件:最基础的物料,目前飞冰的基础组件达到 55+,具有高度可复用性。 + +* 区块:通过对大量的中后台系统常用的场景进行分类、对比和抽象,基于基础组件组合而成,目前飞冰的区块达到 110+,可以通过 iceworks 进行快速组合搭建应用,减少重复的开发,提升效率。 + +* 布局:在中后台系统中布局通常较为统一,以 `顶部-侧边布局-通栏` 模式为主,为此我们提供了 4+ 常见的布局,支持 `light` 和 `dark` 两套主题。 + +* 模板:基于已有的区块搭建而成,目前提供了 4+ 的特定领域的模板,可以从零开始搭建应用,也可以选择特定类型的模板开始使用。 + +## 联系我们 + +* 邮件: +* 反馈/建议: +* 答疑钉钉群: diff --git a/docs/advanced/custom-theme.md b/docs/advanced/custom-theme.md new file mode 100644 index 0000000000..61302ed3a5 --- /dev/null +++ b/docs/advanced/custom-theme.md @@ -0,0 +1,39 @@ +--- +title: 修改主题配色 +order: 3 +category: 进阶指南 +--- + +## 为什么要修改 + +ICE Design 为 ICE 体系内的组件和物料提供了指导性规范,但是我们也支持在一定程度内对样式风格进行个性化定制。 + +## 开放的定制能力 + +* 皮肤风格 (theme) + * 由 `Layout` 提供能力支持,当前可传入 `dark` 或者 `light` +* 主品牌色 (primaryColor) + * 支持 CSS 提供的颜色格式规范 + * Hex: 如 `#ff0000`, `#f00` + * RGB: 如 `rgb(255, 0, 0)` + * 颜色常量: 如 `red`, `yellow` +* 副品牌色 (secondaryColor) + * 同上 + +我们也在考虑开放更多可供定制的变量,如果以上变量不能满足你的需求,可以给我们提 issue 进行讨论。 + +## 如何修改 + +请先确保您的 `ice-scripts` 已经升级到 `1.0.8` 及以上版本。 + +修改项目目录下的 `package.json` 文件如下所示: + +```json +{ + "themeConfig": { + "theme": "dark", + "primaryColor": "red", + "secondaryColor": "grey" + } +} +``` diff --git a/docs/advanced/how-to-make-form.md b/docs/advanced/how-to-make-form.md new file mode 100644 index 0000000000..6033aa73a2 --- /dev/null +++ b/docs/advanced/how-to-make-form.md @@ -0,0 +1,223 @@ +--- +title: 如何制作表单 +order: 4 +category: 进阶指南 +--- + +在中后台前端应用中,表单是一个非常常见的需求,用于填写一些信息、校验、编辑、提交等。本文档专门介绍如何使用 ICE 快速实现常见的后台表单类需求。 + +为了简化使用,提高开发效率,我们推荐使用 ICE 表单粘合剂组件 `@icedesign/form-binder` 配合 ICE 提供的一系列表单类组件(如 Input, Select 等) 的组合来进行开发。 + +在这里我们准备了非常常见的业务场景作为演示,**模态框 + 表格 + 表单** 组合的业务场景。 + +![](https://img.alicdn.com/tps/TB1GZQhNFXXXXatXpXXXXXXXXXX-1420-506.png) + +在各个表单组件包裹 `FormBinder` 组件,并声明对应的 `name` `FormBinder` 会自动与这些组件的数据进行关联,之后我们就要利用 `FormBinder` 自带的功能进行获取、校验、回填处理。 + +## 回填数据 + +在使用 `FormBinder` 组件后,我们不需要为单独的表单组件(如 Input,Radio 等)进行 value 值的回填。我们可以在 `FormBinderWrapper` 上用 `value` 统一进行回填,使用对象的形式,其中键值会自动与 `FormBinder` 上的 `name` 进行关联,就像 HTML5 标准表单一样: + +```jsx +import { + FormBinderWrapper, + FormBinder, + FormError, +} from '@icedesign/form-binder'; + + +
+ + + + + + + + + + + + + + + + + + +
+
+``` + +由于 Form 此时是一个受控组件,清空数据等操作可以对 `value` 赋空值进行: + +```jsx +class Demo extends Component { + state = { + formValue: { + id: '1' + name: '卓凌', + age: 20, + sex: 'male' + } + }; + + clearForm = () => { + this.setState({ + formValue: {} + }); + }; + + render() { + return ( + +
+ + + + + + + + + + + + + + + + + + + +
+
+ ); + } +} +``` + +## 主动触发校验 + +如果想要主动校验全部表单,则需要在 FormBinderWrapper 组件上面添加 ref,在合适的地方调用实现,全部校验发现报错表单会自动跳转到对应表单。 + +```jsx +import { + FormBinderWrapper, + FormBinder, + FormError, +} from '@icedesign/form-binder'; + +validateForm = () => { + this.form.validateAll((errors, values) => { + console.log('errors', errors, 'values', values); + }); +}; + + { this.form = ref; }} + value={value} + onChange={this.formChange} +> + ... + + +``` + +### 校验规则的类型陷阱 + +在前端开发中,有一些类型陷阱是需要开发者特别注意的。用户输入的 `Input` 等,它的类型默认都是字符串 `String`,当然你可以回填一个 `Number` 类型的数据给 `Input`,但是在取值的时候它会被转换成字符串。 + +```jsx + + + +``` + +## 总结 + +至此,已经讲解完了如何使用 `FormBinder` 组件并进行相关操作,以及可能遇到的问题。简单的回顾: + +1. 首先使用 `FormBinderWrapper` 包裹所有表单项。 +2. 在 `FormBinder` 组件上使用 `name` 进行数据关联,配置校验规则。 +3. 使用 `FormBinderWrapper` 的 `value` 属性进行数据回填。 +4. 使用 ref 上的 `valildateAll` 方法校验当前表单数据并进行后续操作。 + +## FAQ + +### Q:表单作为一个子组件的时候,我怎么把需要回填的值传递下去并回填? + +React 组件有一个生命周期 componentWillReceiveProps 是在当前组件 props 变动的时候触发,此时可以在这个生命周期方法中传递 value: + +```jsx +class Demo extends React.Component { + + ... + + state = { + formValue: {} + }; + + componentWillReceiveProps(nextProps) { + // nextProps 是上层传下来需要回填的数据 + if(nextProps.name) { + const { formValue } = this.state; + this.setState({ + formValue: { + ...formValue, + name + } + }); + } + } + + render() { + return ( + ... + ); + + } +} +``` + +### Q:如何在表单组件 onChange 的时候做一些额外的事情? + +直接使用表单组件的 `onChange` 或者 FormBinderWrapper 的 `onChange` 即可,没有任何魔法。 + +```jsx +handleInputChange = (input) => { + console.log('Input 的值现在是', input); +}; +// ... +; +``` + +```jsx +handleFormChange = (value, changedByName) => { + const changedValue = value[changedByName]; + console.log('由于' + changedByName + '变成了' + changedValue); + console.log('表单的值现在是', value); +}; +// ... + +
+ + + +
+
; +``` diff --git a/docs/advanced/webpackrc.md b/docs/advanced/webpackrc.md new file mode 100644 index 0000000000..525cd03a9d --- /dev/null +++ b/docs/advanced/webpackrc.md @@ -0,0 +1,102 @@ +--- +title: 定制构建器 +order: 3 +category: 进阶指南 +--- + +ICE 的[工程](https://github.com/alibaba/ice/tree/master/tools/ice-scripts)使用了 `webpack` 作为构建的基石,并且提供了零配置的构建配置,但是如果你对 `webpack` 配置有特别的需求,可以参考本文对默认配置进行定制。 + +## 要求 + +* devDependencies 里的 ice-scripts 依赖版本号为 1.1.0 及以上 + +## 如何配置 + +ICE 项目支持在项目根目录创建 `.webpackrc.js` 文件对 `webpack` 项目进行定制和覆盖,`.webpackrc.js` 文件需要导出一个 `webpackConfig` 对象,其支持的参数可以参考 `webpack` [官方文档](https://webpack.js.org/concepts/output/)。 + +`.webpackrc.js` 文件采用您操作系统中安装的 Node.js 所支持的语法,所以您可以使用除了 `import`, `export` 等之外的几乎所有 ES6 语法。 + +```js +module.exports = { + // webpack config +}; +``` + +## 配置举例 + +* 修改编译输出的路径为 `dist/` + +```js +const { resolve } = require('path'); + +module.exports = { + output: { + path: resolve('dist'), + }, +}; +``` + +* 添加反向代理服务 + +```js +const proxyTarget = 'http://127.0.0.1:7001/'; + +module.exports = { + devServer: { + proxy: { + '/**': { + target: proxyTarget, + changeOrigin: true, + bypass: function(req, res, proxyOpt) { + // 添加 HTTP Header 标识 proxy 开启 + res.set('X-ICE-PROXY', 'on'); + res.set('X-ICE-PROXY-BY', proxyTarget); + }, + }, + }, + }, +}; +``` + +* `webpack` 支持配置多入口实现在一个工程中同时构建多个单页面应用,以下为多 `entry` 的 `.webpackrc.js` 配置示例 + +```js +const { resolve } = require('path'); +const HtmlWebpackPlugin = require('html-webpack-plugin'); + +module.exports = { + entry: { + index: ['src/index.js'], + app: ['src/index.js'], + }, + output: { + path: resolve('dist'), + filename: '[name].[hash].js', + }, + plugins: [ + new HtmlWebpackPlugin({ + title: 'index', + chunks: ['index'], + template: resolve('./public/index.html'), + filename: 'index.html', + }), + new HtmlWebpackPlugin({ + title: 'app', + chunks: ['app'], + template: resolve('./public/index.html'), + filename: 'app.html', + }), + ], + devServer: { + before(app) { + app.use(function(req, res, next) { + // 重定向 html 的请求到 /build/ dev 服务上 + if (req.url === '/' || req.path.endsWith('.html')) { + req.url = '/build' + req.url; + } + next(); + }); + }, + }, +}; +``` diff --git a/docs/advanced/work-with-create-react-app.md b/docs/advanced/work-with-create-react-app.md new file mode 100644 index 0000000000..49894a25d9 --- /dev/null +++ b/docs/advanced/work-with-create-react-app.md @@ -0,0 +1,292 @@ +--- +title: 在 create-react-app 中使用 +order: 1 +category: 进阶指南 +--- + +[create-react-app](https://github.com/facebook/create-react-app) 是社区广泛使用的 React 开发工具,本文讲述如何在使用 create-react-app 创建的项目中使用飞冰,以及如何通过 Iceworks 生成 create-react-app 项目。 + +# 如何在使用 create-react-app 创建的项目中使用 + +## 初始化项目 + +使用 `npx` 命令执行 `create-react-app` 创建一个项目 + +```bash +npx create-react-app my-app +cd my-app +npm start +``` + +> npx 命令在 npm 5.2+ 自带,如果没有 npx 您可能需要按照官方文档操作 + +此时浏览器会打开本地调试地址 http://localhost:3000/ 。 + +## 引入组件 + +根据组件文档,安装对应的组件。 + +```bash +npm install @icedesign/base @icedesign/img --save +``` + +修改 `src/App.js`,引入 `Button` 和 `Img` 组件。 + +```jsx +import React, { Component } from 'react'; +import Button from '@icedesign/base/lib/button'; +import Img from '@icedesign/img'; +import './App.css'; + +const image = + 'https://img.alicdn.com/tfs/TB1saOBbYGYBuNjy0FoXXciBFXa-218-58.png'; + +class App extends Component { + render() { + return ( +
+ + +
+ ); + } +} + +export default App; +``` + +修改 `src/App.css`,在文件顶部引入组件的样式。 + +```css +@import 'http://github.com/~@icedesign/base/dist/ICEDesignBase.css'; +@import 'http://github.com/~@icedesign/img/dist/Img.css'; + +.App { + text-align: center; +} + +... +``` + +现在你应该能看到页面上已经有了蓝色的 `Button` 组件,接下来就可以继续选用其他组件开发应用了。 + +其他开发流程你可以参考 `create-react-app` 的官方文档。 + +这种方式引入的基础组件样式为全量引入,如果需要按需引入请看下面。 + +## 自定义按需引入 + +上面的方法虽然能够正常运行组件,但是可以发现样式是全量引入的,`Button` 的引入需要额外增加 `lib/button` 的二级路径。 + +要解决这些问题,我们需要对 `create-react-app` 进行一些工程定制。我们建议使用社区流行的 [react-app-rewired](https://github.com/timarney/react-app-rewired) 进行自定义配置。 + +首先安装 `react-app-rewired` + +```bash +npm i react-app-rewired --save-dev +``` + +修改 `package.json` 文件的 `scripts` 字段 + +```json +{ + "scripts": { + "start": "react-app-rewired start", + "build": "react-app-rewired build", + "test": "react-app-rewired test --env=jsdom" + } +} +``` + +在您的项目根目录创建 `config-overrides.js` 文件来修改默认配置。 + +### 使用 babel-plugin-import 实现按需加载 + +[babel-plugin-import](https://github.com/ant-design/babel-plugin-import) 是一个用于按需加载组件代码和样式的 babel 插件,现在我们尝试安装它并修改 `config-overrides.js` 文件。 + +```bash +npm i babel-plugin-import --save-dev +``` + +```diff ++ const { injectBabelPlugin } = require('react-app-rewired'); + + module.exports = function override(config, env) { ++ config = injectBabelPlugin(['import', { ++ libraryName: '@icedesign/base' ++ }], config); + return config; + }; +``` + +### 使用 webpack-plugin-import 实现样式自动引入 + +`webpack-plugin-import` 是用于自动加载样式的 webpack 插件,它的原理是对引入模块路径下存在 `style.js` 的样式进行自动加载,这意味着您可能需要同时配置 `less` 或 `sass` 等预处理器的 `loader`。 + +修改 `config-overrides.js` 的内容 + +```js +// ... +const WebpackPluginImport = require('webpack-plugin-import'); + +module.exports = function override(config, env) { + // ... + config.plugins.push( + new WebpackPluginImport([ + { + libraryName: /^@icedesign\/base\/lib\/([^/]+)/, + stylePath: 'style.js', + }, + { + libraryName: /@icedesign\/.*/, + stylePath: 'style.js', + }, + ]) + ); + // ... + return config; +}; +``` + +### 配置 sass-loader 和 ice-skin-loader + +`ICE` 官方提供的组件依赖了 Sass 作为 CSS 预处理器,所以您需要手动配置并引入 `sass-loader`。同时 `ICE` 使用了 `ice-skin-loader` 支持自定义皮肤的定制。首先安装以下依赖。 + +```bash +npm i @icedesign/skin --save +npm i sass-loader node-sass ice-skin-loader --save-dev +``` + +在根目录创建 `rewire-scss.js` 文件,添加以下内容。 + +```js +const getRules = (config) => + config.module.rules.find((rule) => Object.keys(rule).includes('oneOf')).oneOf; +const findFileLoaderRuleFn = (rule) => + typeof rule.loader === 'string' && rule.loader.includes('file-loader'); +const findStyleLoaderRuleFn = (rule) => + rule.test.toString() === /\.css$/.toString(); + +function rewireSass(config, env, sassOptions = {}) { + // find the non-javascript ruleset in the webpack config + const rules = getRules(config); + + // find the file-loader and add a rule excluding sass files from being loaded as text + config.module.rules[1].oneOf + .find(findFileLoaderRuleFn) + .exclude.push(/\.scss$/); + + // find the current rule for loading css files + const styleLoaderRule = rules.find(findStyleLoaderRuleFn); + + // allows the test to be pre-defined by react-scripts as an array or a single regex + const currentTests = Array.isArray(styleLoaderRule.test) + ? [...styleLoaderRule.test] + : [styleLoaderRule.test]; + + // add regexes for scss files + styleLoaderRule.test = [...currentTests, /\.scss$/, /\.sass$/]; + + styleLoaderRule.use.push({ + loader: require.resolve('sass-loader'), + options: sassOptions, + }); + styleLoaderRule.use.push({ + loader: require.resolve('ice-skin-loader'), + options: { + themeFile: require.resolve('@icedesign/skin'), + }, + }); + + return config; +} + +module.exports = rewireSass; +``` + +修改 `config-overrides.js` 的内容 + +```js +// ... +const rewireSass = require('./rewire-scss'); + +module.exports = function override(config, env) { + // ... + config = rewireSass(config); + // ... + return config; +}; +``` + +### 如何使用 + +在项目的任意 `js` 文件中,您都可以使用类似如下的方法直接按需引入某一组件,不用担心全量引入和样式缺失的问题。 + +```jsx +import { Button } from '@icedesign/base'; +import Img from '@icedesign/img'; + +; +``` + +# 如何通过 Iceworks 生成 create-react-app 项目 + +如果你觉得使用 create-react-app 自定义太麻烦,我们也提供了基于 Iceworks 模板创建项目的流程生成 create-react-app 项目,使用 react-app-rewired 进行自定义配置,支持按需引入飞冰基础组件,添加区块。 + +## 初始化项目 + +在 Iceworks 模板界面选择 create-react-app 模板,以该模板创建项目 + +![Iceworks](https://img.alicdn.com/tfs/TB1GTwcm7yWBuNjy0FpXXassXXa-1908-1368.png) + +## 预览 + +创建项目后,可以在 Iceworks 项目界面启动调试服务, 会自动打开浏览器窗口,看到如下页面说明创建项目成功 + +![create-react-app](https://img.alicdn.com/tfs/TB1u1gxm1uSBuNjy1XcXXcYjFXa-1768-1064.png) + +## 添加区块 + +使用 Iceworks create-react-app 模板创建的项目与官方 create-react-app 模板基本保持一致,不同的点在于使用了 react-app-rewired 进行自定义配置,支持按需引入 ICE 基础组件,目录结构如下: + +### 目录结构 + +``` +. +├── README.md +├── .gitignore +├── config-overrides.js +├── package.json +├── public +│ ├── favicon.ico +│ ├── index.html +│ └── manifest.json +├── rewire-scss.js +└── src + ├── App.css + ├── App.js + ├── App.test.js + ├── index.css + ├── index.js + ├── logo.svg + └── registerServiceWorker.js +``` + +### 添加区块 + +通过 Iceworks 新建页面添加的区块默认会在项目 `src` 下新建 `pages` 目录,用于存放添加的区块,如添加一个 TabTable 区块后,目录结构如下: + +``` +. +└── src + ├── pages/ // 新增 pages 目录 + ├── App.css + ├── App.js + ├── App.test.js + ├── index.css + ├── index.js + ├── logo.svg + └── registerServiceWorker.js +``` + +使用 create-react-app 模板创建的项目默认只支持添加区块;接下来,可以按照你熟悉的开发方式自定义开发。 diff --git a/docs/basis/api-communicate.md b/docs/basis/api-communicate.md new file mode 100644 index 0000000000..89d1a91954 --- /dev/null +++ b/docs/basis/api-communicate.md @@ -0,0 +1,125 @@ +--- +title: 如何实现前后端通信 +order: 9 +category: 入门指引 +--- + +实现前后端通信,我们推荐使用 axios 或 DataBinder 与后端 HTTP API 接口通信的方案。 + +传输数据格式描述使用 JSON。 + +## 使用 axios 进行请求 + +我们推荐使用 `axios` 方法库提供基础的 Ajax 能力,也可以使用 DataBinder 为组件(比如 Table)绑定 AJAX 接口数据,方便查询异步数据以及错误处理。 + +首先安装模块: + +```bash +npm install axios --save +``` + +引入对应组件,并使用 `axios` 函数获取数据: + +```jsx +import axios from 'axios'; + +export default class extends Component { + componentDidMount() { + // 使用 axios 获取数据 + axios(remoteURL).then((response) => { + const { body } = response; + this.setState({ + data: body, + }); + }); + } + + render() { + // ... + } +} +``` + +> 更多请参考 [axios 的文档](https://github.com/axios/axios) + +## 使用 DataBinder 为组件绑定数据 + +DataBinder 是 ICE 推出的基于约定,在组件上绑定数据和自动更新数据的组件,让你专注于 UI 显示逻辑,从而屏蔽数据状态管理的开发成本。 + +**使用方法** + +```jsx +@DataBinder({ + '模块名 key': { + url: 'xxxx.json', + method: 'post', + // 请求附带的 request 参数,method post 下是 data 参数,method get 下是 params + data: { + page: 1, + }, + // AJAX 部分的参数完全继承自 axios ,参数请详见:https://github.com/axios/axios + // 下面是请求会返回的默认数据 + defaultBindingData: { + // ...字段需要与 xxxx.json 接口返回的字段一一对应 + }, + }, +}) +class ListView extends Component { + // ... + render() { + const { account } = this.props.bindingData; + + return ( +
+

用户名:{account.userName}

+

年龄:{account.userAge}

+
+ ); + } +} +``` + +> 更多请参考 [DataBinder 的文档](#/component/databinder) + +## 最佳实践 + +对于一些嵌套较深的对象数据,如果后端返回为空,就可能导致渲染异常,所以需要进行先行判断: + +**注意:以下是错误的用法** + +```js +this.setState({ + foo: data.list.foo, +}); +``` + +**最佳实践** + +```js +if (data && data.list && data.list.foo) { + this.setState({ + foo: data.list.foo, + }); +} else { + // foo 未取到 +} +``` + +## 同源限制导致的跨域问题 + +浏览器安全的基石是"同源政策",所谓"同源"指的是"三个相同"。 + +* 协议相同 +* 域名相同 +* 端口相同 + +举例来说,`http://www.example.com/dir/page.html`这个网址,协议是`http://`,域名是`www.example.com`,端口是`80`(默认端口可以省略)。它的同源情况如下。 + +* `http://www.example.com/dir2/other.html`:同源 +* `http://example.com/dir/other.html`:不同源(域名不同) +* `http://v2.www.example.com/dir/other.html`:不同源(域名不同) +* `http://www.example.com:81/dir/other.html`:不同源(端口不同) + +同源政策的目的,是为了保证用户信息的安全,防止恶意的网站窃取数据。 + +跨域指的是前端页面请求一个非同源的 API 地址,这种请求一般来说会被浏览器阻挡。 diff --git a/docs/basis/env-config.md b/docs/basis/env-config.md new file mode 100644 index 0000000000..d879e49df6 --- /dev/null +++ b/docs/basis/env-config.md @@ -0,0 +1,39 @@ +--- +title: 开发环境配置 +order: 1 +category: 入门指引 +--- + +飞冰的开发环境依赖于 Node.js,如您已经安装了 Node.js 且版本号符合 \*LTS 版本,则可以忽略此文档。 + +### 安装 Node.js 环境 + +#### macOS 用户 + +我们建议您使用 \*nvm 来管理 Node.js 的安装。 + +打开终端,执行如下命令 + +```bash +curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.8/install.sh | bash +``` + +完成后重启终端,执行 `nvm install --lts` 来安装最新 LTS 版本的 Node.js + +#### Windows 用户 + +访问 Node.js 的官网,下载对应平台且标记为 LTS 版本的安装包,并执行安装,安装成功后在终端执行: + +### 验证安装的 Node.js 版本 + +在终端中执行如下命令 (Windows 下可以是 Git Bash 或其它终端模拟器) + +```bash +node -v +npm -v +``` + +终端打印出 Node.js 和 npm 的版本,则表示安装成功。 + +> * LTS: 指的是 Node.js 的长期维护版本,您可以在这里 https://github.com/nodejs/Release#release-schedule 看到 Node.js 各版本的官方持续维护期限 +> * nvm: 请参考 https://github.com/creationix/nvm diff --git a/docs/basis/find-components.md b/docs/basis/find-components.md new file mode 100644 index 0000000000..705993c45f --- /dev/null +++ b/docs/basis/find-components.md @@ -0,0 +1,23 @@ +--- +title: 如何查找社区组件 +order: 11 +category: 入门指引 +--- + +飞冰组件体系基于 NPM 包管理,因此除了我们提供的高质量组件之外,你还可以自行检索使用 NPM 社区里超过 37w+ 的组件,下面介绍下通常我们是怎么查找这些组件拿来用的。 + +#### 1. 使用英语在 google 或者 github 站点上检索 + +优质的组件往往会采用英语(为了服务全世界,很多中国人开发的也是用英语介绍),所以针对你的需求使用英文关键词会极大的提升检索效率和结果质量。 + +比如我们希望找到管理 react state 更好的方案或者库,可以试着搜索 "react state management github" 或者 "react state management npm" 可以找到几个选项,其中可以看到 [mobx](https://github.com/mobxjs/mobx) 在 github 上面有非常多的 star,证明这个包比较可靠、使用者比较多,可以优先选择使用。 + +#### 2. 查找文档找到安装方法和使用方法 + +目前前端相关的项目,基本都会提供 NPM 的安装方式,基于 NPM 进行包管理。查找文档你可能会看到类似这样的安装说明: + +![](//img.alicdn.com/tfs/TB14B7YOVXXXXcRXpXXXXXXXXXX-1914-982.png) + +通常来说,组件的安装方式是执行命令 `npm install [package name] --save`。 + +之后需要参照相关文档进行使用,如果你觉得符合你的需求挺好用,欢迎推荐给我们补充到站点上面。如有问题也可以随时咨询。 diff --git a/docs/basis/git-assets-work.md b/docs/basis/git-assets-work.md new file mode 100644 index 0000000000..8b3b996ac9 --- /dev/null +++ b/docs/basis/git-assets-work.md @@ -0,0 +1,75 @@ +--- +title: Git 仓库开发实践 +order: 3 +category: 入门指引 +--- + +使用 Iceworks 创建项目后,会自动生成项目的脚手架文件,下面就对这些文件的仓库管理进行说明。 + +## 目录结构 + +以 `ICE Design Pro` 模板为例: + +``` +ice-design-pro +├── dist // 打包资源 +├── mock // 模拟数据 +├── public // 静态资源 +├── src +│ ├── components // 公共组件 +│ ├── layouts // 通用布局 +│ ├── pages // 页面 +│ ├── index.js // 应用入口 +│ ├── menuConfig // 导航配置 +│ ├── routerConfig // 路由配置 +│ └── router.jsx // 路由入口 +├── tests // 测试 +├── .gitignore // git 忽略目录配置 +├── .editorconfig // 代码风格配置 +├── .eslintignore // eslint 忽略目录配置 +├── .eslintrc // eslint 配置 +├── package.json // package.json +└── README.md // 项目说明 +``` + +## 使用命令行操作 + +这里介绍使用命令行操作 git 仓库的基本命令,如果您使用 GUI 工具 (如 SourceTree) 进行管理,请遵循该工具的帮助文档。 + +### 初始化 Git 仓库 + +在初始化的项目根目录下执行以下命令,并将初始化的文件推送到 git 仓库: + +```bash +$ git init +$ git add . +$ git commit # 输入提交信息并保存 +``` + +### 2. 提交项目到远程 Git 仓库 + +您需要使用 github 或者 gitlab 创建一个远程仓库,由于 Git 是一种分布式仓库管理工具,如果您打算只在本地使用这些代码, 那么可以忽略这一步。 + +```bash +$ git remote add origin git://your-repo-url +$ git push origin master -u +``` + +## 分支管理 + +Git 仓库创建好后,此时只有一个 master 主干,不允许向 master 提交代码,后续开发都应该创建分支在分支上开发。 + +### 创建新分支 + +创建一个名为 feature/0.1.0 的分支。并将分支提交到 gitlab 仓库上。 + +```bash +$ git checkout -b feature/0.1.0 # 创建分支 +$ git push origin feature/0.1.0 # 提交分支 +``` + +这样就创建好一个名为 daily/0.1.0 的分支了。 分支名是可以任意定义的,比如你可以创建自己的功能命名的分支, 如 `git checkout -b feature/add-login` 表示一个登录功能的分支。 + +### 提交变更代码 + +在编写代码完成后,或者某个功能完成时,可以将变更的代码提交到远端分支,准备部署发布。 diff --git a/docs/basis/intro-javascript.md b/docs/basis/intro-javascript.md new file mode 100644 index 0000000000..f972506a74 --- /dev/null +++ b/docs/basis/intro-javascript.md @@ -0,0 +1,406 @@ +--- +title: JavaScript 基础知识 +order: 4 +category: 入门指引 +--- + +写前端必须要掌握一定基础的 JavaScript 语言知识,本文档将介绍绝大部分常用的 JavaScript 语言基础知识,同样概念添加 Java 语言对比,帮你快速学习理解。 + +## JavaScript 语言概述和开发环境、运行环境配置 + +JavaScript 是一门脚本语言,用在网页上增强页面功能,是一门动态语言因此不需要进行编译、部署。 + +JavaScript 是弱类型的语言,语法比较简单,掌握基本语法之后怎么写都可以,比 Java 灵活的多,同时不需要依赖 IDE,任何文本编辑器都可以进行开发。当然如果你用 IDEA 等 IDE 更是锦上添花。 + +JavaScript 比较常见的运行环境就是 Web 浏览器,比如 Chrome 直接打开 console 输入 JavaScript 代码即可运行实时看到结果: + +![](https://img.alicdn.com/tps/TB1tLD7NFXXXXbmXpXXXXXXXXXX-992-616.png) + +> 提示:在 Chrome 中,右击网页选择『检查』即可打开开发者工具,可以切换到 console 面板。详情可以看[如何使用控制台](https://leeon.gitbooks.io/devtools/content/learn_basic/using_console.html)。 +> 提示:控制台比较常用的有 console.log 方法,它可以打印一些内容、变量值等到你的控制台辅助开发,等同 Java 中的 System.out.println 方法。 + +## JavaScript 语法基础 + +### 变量定义 + +* let 定义普通变量(推荐),详情:http://es6.ruanyifeng.com/#docs/let#let命令。 +* const 定义常量,后面只能读不能写,详情:http://es6.ruanyifeng.com/#docs/let#const命令。 +* var 定义普通变量,不建议使用。 + +var 由于缺失某些特性,不建议使用,关于 let 和 var 的对比,详情见:https://www.zhihu.com/question/47456978 。 + +由于 JavaScript 是弱类型语言,因此你不需要声明变量的数据类型。 + +JavaScript: + +```js +let x = 20; +``` + +Java: + +```java +float x = 20.0; +double x = 20.0; +int x = 20; +``` + +具体支持的数据类型参照下面文档。 + +### 数据类型 + +数据类型基础知识详见:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Data_structures ,这里针对常用的几种进行重点讲解。 + +基础类型包括:Undefined、Null、Boolean、Number、String,引用类型包括:Object、Array、Function。当一个变量值为引用类型的时候,直接赋值其他变量传递的是引用。同样的,引用的数据在某个地方改变了值会影响所有调用这个变量的地方。这跟 Java 里面引用概念一样。 + +#### undefined 和 null + +声明一个变量没有赋值,直接访问当前变量可以得到 `undefined`。不同于 Java 针对不同数据类型有不同的初始值: + +JavaScript: + +```js +let x; +console.log(x); // -> undefined +``` + +Java: + +```java +int x; +System.out.println(x); // -> 0 +``` + +访问一个对象上不存在的 key 也会取到 undefined。 + +```js +let a = {}; +console.log(a.b); // -> undefined +``` + +null 表示空值。它不同于 undefined,它是有值的只不过是一个空值,而 undefined 是未定义的临时兜底的缺省值。undefined 和 null 具体的区别请参见:http://www.ruanyifeng.com/blog/2014/03/undefined-vs-null.html 。 + +#### number、boolean、string + +基本的数据类型: + +```js +console.log(typeof 10); // -> number +console.log(typeof '10'); // -> string +console.log(typeof true); // -> boolean +console.log(typeof "true"); // -> string +``` + +JavaScript 中带引号的均为字符串,可以是单引号也可以是双引号。不同于 Java 字符串只能使用双引号表示。JavaScript 没有 int、float 和 double 之分。 + +#### array + +数组类型,栈结构,有序数组。每个 item 可以是任意类型的值,数据类型类似 Java 的 ArrayList ,比如: + +```js +// 字符串数组 +['string', 'aaa'] + +// 对象和字符串混合数组 +[{ + aa: 'aaa', + bb: 'bbb', +}, 'string'] + +// 函数数组 +[() => { + return '这是一个函数' +}, () => { + return '这是一个函数' +}] +``` + +如果需要取得特定需要的值,直接获取(比如获取第一个数据): + +JavaScript: + +```js +array[0]; +``` + +Java: + +```java +list.get(0); +``` + +数组是有序的,遍历数组需要使用流程控制语句 for 等。为了方便,array 内置了一些数组常用操作方法可以简化常用操作,详情可见:。 + +比较常用 [forEach](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach) 和 [map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) 方法,可以重点关注下用法。 + +简易循环举例: + +JavaScript: +```js +let list = []; +list.push('aa'); +list.push('bb'); + +for(let i=0; i { + console.log(val, i); +}); +``` + +Java: + +```java +List list = new ArrayList(); +list.add('aa'); +list.add('bb'); + +for(int i=0; i { + System.out.println(val); +}); +``` + +相比 Java 的 add 操作,JavaScript array 的出栈入栈删除的方法名略有不同,常见的 push 入栈、pop 出栈,具体的参照 http://javascript.ruanyifeng.com/stdlib/array.html 。 + +#### object + +对象类型,无序,需要指定 key 等信息关联值,类似 Java 的 HashMap,比如: + +JavaScript: + +```js +let obj = { + name: 'string 字符串', + home: { + province: '山东' + } +}; + +obj.age = 18; + +console.log(obj.home.province); +let key = 'age'; +console.log(obj[key], obj['age']); +delete obj.name; +``` + +Java: + +```java +HashMap obj = new HashMap(); +obj.put('age', 18); + +obj.get('age'); +obj.remove('age'); + +``` + +如果不确定 key 的值(变量)可以使用如下方法调用: + +```js +let key = 'age'; +obj[key]; // -> 18 +``` + +因此可以用来做 key value 的数据映射使用。由于弱类型存储的值可以多种多样,比 Java 使用起来要容易一些。详情: + +#### function + +函数类型,用来创建一个函数,通常会返回一个数据。 + +JavaScript: + +```js +function fun(a, b) { + return a + b; +} +fun(1, 2); // -> 3; +``` + +Java: + +```java +public static int fun(int a, int b) { + int result; + result = a + b; + + return result; +} +fun(1, 2); +``` + +函数是一个可执行的小程序,根据参数处理一些逻辑并返回一段新的数据,在 JavaScript 中用非常多,为此 ES6(新版 JavaScript 语言规范)新增了箭头函数语法,用来简化函数书写: + +```js +let add = function(a, b) { + return a + b; +}; + +等同于 + +let add = (a, b) => { + return a + b; +}; + +循环语句中也非常直观方便: + +list.forEach((a, b) => { + console.log(a + b); +}); +``` + +箭头函数有个重要的特点就是自动绑定了当前的作用域,作用域的概念,JavaScript 和 Java 的一样,JavaScript 中可以使用 bind、call、apply 三个方法改变函数执行的作用域,简单区别如下: + +* bind 方法,创建一个新的函数的**引用**并绑定到一个作用域特定作用域上面,同时支持传参。`bind(作用域对象, 参数1, 参数2)` +* apply、call 方法,直接调用执行该函数,在执行的时候将函数内部的作用域绑定到参数指定的作用域。`call(作用域)` + +这几个方法详情请见: 。通常可能会在 JavaScript 的作用域上产生疑惑,没关系随时联系 ICE 小组进行处理解答。 + +箭头函数声明和特性: + +函数作用域: + +设置函数参数的默认值: + +#### 类型转换 + +类型转换可以通过调用类型的类进行转换,比如将变量 a 转换成 Number 类型,可以使用: + +JavaScript: + +```js +let a = '10'; +a = Number(a); +``` + +Java: + +```java +int x; +(double)x; +``` + +除了这种比较正规的方法之外,跟 Java 一样还有其他惯用方法进行转换。 + +##### 转换 number 类型 + +JavaScript: + +```js +let a = '12.33'; +console.log(parseInt(a)); // -> 12 number +console.log(parseFloat(a)); // -> 12.33 number +``` + +Java: + +```java +int i = Integer.parseInt(“123”); +``` + +##### 转换 string 类型 + +同 Java 每个类型的值都含有 toString() 方法。 + +```js +let a = 12.33; +console.log(a.toString()); // -> '12.33' + +将 Object 转成 JSON 字符串 + +let obj = { + a: 'aa', + b: 'bb' +}; +console.log(JSON.stringify(obj)); // -> '{"a":"aa","b":"bb"}' +let objStr = '{"a":"aa","b":"bb"}'; +console.log(JSON.parse(objStr)); // -> {a:"aa", b:"bb"} +``` + +##### 转换 boolean 类型 + +JavaScript 中的 boolean 的值比较多,空字符串、数字 0、null、undefined 均为布尔值的 false。此外 `!` 表示取当前布尔值的反值,可以通过 `!!` 巧妙的将值转换成布尔值类型的数据。 + +JavaScript: + +```js +console.log(!!'a'); // -> true +console.log(!!''); // -> false 空字符串 +console.log(!!0); // -> false 数字 0 +console.log(!!10); // -> true +console.log(!!null); // -> false +console.log(!!undefined); // -> false +console.log(!![].length); // -> false +``` + +### 流程控制、比较、运算符等 + +* 流程控制 + * If: + * Switch: + * For: + * While: +* 比较: +* 运算符: + +基本跟 Java 一样,下面介绍几个 JavaScript 比较常用、特殊的知识点: + +#### == 和 === 的区别 + +JS 是弱类型语言,=== 表示全等判断,会把类型也进行比较: + +```js +2 == '2' // -> true +2 === '2' // -> false +``` + +#### + 运算符会改变数据类型 + +运算符会导致数据类型的改变,这是因为运算符同时表示多种含义导致。+ 运算符既可以链接字符串,也可以计算数字,使用时需要注意: + +```js +2 + 2 // -> 4 number +2 + '2' // -> '22' string +``` + +### ES6 新版语法增强功能 + +ES6 是新一代 JavaScript 语法规范,里面新增了非常多的语法和功能,而且往 Java 等传统语言靠拢。比如 class 类定义、箭头函数、真正的 Set、Map 数据类型等。下面仅列出比较推荐的用法,有一些用法由于不太稳定暂时不推荐使用。 + +##### `...obj` 扩展运算符 + +object 的赋值需要遍历相关字段,比如: + +```js +let bb = { + age: 18, + sex: 'male', +}; +let aa = { + name: '浩睿', +}; +// 在 aa 上面新增 bb 的属性需要 +aa.age = bb.age; +aa.sex = bb.sex; +``` + +这样就比较麻烦,你必须知道所有 key 而且每次新增都需要改动相关字段。为此,ES6 规范将扩展运算符(`...`)引入对象。就上面的例子,可以这样写: + +```js +let bb = { + age: 18, + sex: 'male', + name: '后面的同 key 内容会覆盖前面的' +}; +let aa = { + name: '浩睿', + ...bb, +}; +``` + +相当于把某个对象拆开分别赋值,遇到同样的 key 后面内容会覆盖前面的。详情请看: \ No newline at end of file diff --git a/docs/basis/intro-react.md b/docs/basis/intro-react.md new file mode 100644 index 0000000000..1e0b91bce6 --- /dev/null +++ b/docs/basis/intro-react.md @@ -0,0 +1,198 @@ +--- +title: React 基础知识和介绍 +order: 5 +category: 入门指引 +--- + +> React 是 21 世纪人类智慧的结晶。 + +目前几乎绝大部分的组件化方案都是基于 React 实现,因为 React 就是专门为组件化而生的。因此,ICE 后台解决方案也采用了 React 这套方案进行构建。 + +## 了解 React + +本文档不只谈 React 的功能、特性、优势,而是按照实际业务需求对创建一个 React 组件流程做一个介绍,并附带介绍相关特性给出详细参考文档链接。 + +### 创建一个 React 组件 + +首先拿到一系列的页面,我们第一步并不是去马上开发,而是先观察可复用部分抽出成独立的小组件,然后就可以通过拼接组件组装页面了。 + +制作一个组件通常需要展示一段 HTML 代码,创建一个最简单的 React 方法如下: + +```jsx +class HelloMessage extends React.Component { + + render() { + + return ( +
Hello world!
+ ); + } +} +``` +只需要声明一个继承 React Component 的 class 即可创建一个组件,每个组件必须要有一个 render 方法,render 方法的返回值是一段 JSX 代码。 + +JSX 语法跟 HTML 很像,但是还是有一些不同,比较简单的场景下,你可以看做是一样的。[JSX 具体语法请参见这篇文档](https://facebook.github.io/react/docs/jsx-in-depth-zh-CN.html)。 + +创建了一个 class 我们还需要去实例化、执行才可以渲染到页面上,所以我们可以调用下面这句代码将这个组件实际的渲染出来: + +``` +ReactDOM.render(, document.body); +``` + +### 为 React 组件传入数据 + +组件往往是需要展示一些动态数据的,而不是静态的,因此内容不能写死需要获取并传递下去。为此 React 创建了 props 这个概念用来往组件传入数据。 + +```jsx +class HelloMessage extends React.Component { + render() { + return ( +
Hello {this.props.name}
+ ); + } +} + +ReactDOM.render(, mountNode); +``` +渲染组件的时候,按照 HTML 的方式传递一个属性 name 和值 '浩睿',即可在组件内部的任何位置使用 `this.props.name` 拿到这个值进行处理。 + +props 是只读的,用来获取上层组件传递下来的数据。详情请参见:http://stackoverflow.com/questions/27991366/what-is-the-difference-between-state-and-props-in-react + +### React 组件的变化是基于状态的 + +如果设计一个灯开关组件,那么对于这个开关组件它有两种状态,一种是开关开启状态(此时需要连通电线),一种是开关关闭状态(此时需要断开电线),而摁下开关是则是一种触发行为。为此 React 创建了 state 这个概念用来描述组件内部的状态,并支持获取事件进行触发。 + +```jsx +class Switch extends React.Component { + state = { + // 开关状态默认关闭 + switchStatus: false + } + + switch = () => { + // 切换开关的值 + this.setState({ + switchStatus: !this.state.switchStatus + }); + }; + + render() { + + if (this.state.switchStatus) { + return ( +
+

灯已经打开,电线接通

+ +
+ ); + } else { + return ( +
+

灯已经关闭,电线断开

+ +
+ ); + } + } +} +``` + +> Demo 链接:http://ice.alibaba-inc.com/playground/142 + +组件内用到的数据都算作一种状态,存储在 state 里面,当可以拦截某些行为来去改变 state 的值(比如 点击 按钮),需要注意的是改变当前组件的 state 不能直接用 `this.state.switchStatus = true` 来改,必须使用 `this.setState` 方法进行修改。原因是因为状态改变了之后,React 需要重新执行 render 方法进行渲染,此时 render 方法读取 `this.state.switchStatus` 的值就是最新的数据,渲染结果也是最新的。所以必须有一种机制通知 React state 已经变换了,直接改变 `this.state.switchStatus = true` 的值,React 无法检测到状态有変更,因此必须使用 `this.setState({xxx})` 来修改 state 值。 + +React 组件在渲染的时候需要遵循一定的执行顺序,比如 state 改变之后必须重新执行 render 方法等。为了方便控制 React 的执行顺序和流程,React 创建了生命周期的概念用来处理此类功能。 + +关于 props 和 state 的详解,请参见:http://stackoverflow.com/questions/27991366/what-is-the-difference-between-state-and-props-in-react + +### React 组件的生命周期 + +就像一个人一样,出生、赋予属性(props)、成长(state 変更)、衰老死亡(组件销毁),React 组件同样存在这些状态,便于做相关功能处理。 + +```jsx +class Person extends React.Component { + + // 即将出生(刚开始调用) + componentWillMount() { + console.log('我要出生了,我的名字叫 ', this.props.name); + } + + // 出生(开始渲染,准备初始数据,调用 render 方法) + constructor(props) { + super(props); + + console.log('name', this.props.name); + + this.state = { + name: this.props.name, + age: 0 + }; + + // 时间开始转动,5 秒等于 1 岁 + this.timer = setInterval(() => { + this.setState({ + age: this.state.age + 1 + }); + }, 5000); + + console.log('我正在出生'); + } + + + // 出生完毕(调用 render 完成并渲染到页面上) + componentDidMount() { + console.log('我已经出生'); + } + + // 接收了新的属性 + componentWillReceiveProps(nextProps) { + // 换了个新名字,固定的属性 + if (nextProps.name !== this.state.name) { + console.log('我换了个名字:', nextProps.name); + this.setState({ + name: nextProps.name + }); + } + } + + // 要重新渲染了(准备过生日) + componentWillUpdate() { + console.log('我要改变了!'); + } + // 更新渲染完成了(过完生日) + componentDidUpdate() { + console.log('我改变完了!'); + } + + // 要火化了(组件销毁) + componentWillUnmount() { + // 停止时间 + console.log('再见啦!'); + clearInterval(this.timer); + } + + render() { + console.log('我正在改变!'); + return ( +
+

姓名:{this.state.name},年龄:{this.state.age}

+
+ ); + } +} +``` + +> Demo 链接:http://ice.alibaba-inc.com/playground/143 + +每一次 props 或者 state 改变,都会重新渲染组件,为了阻止渲染,React 还提供了 `shouldComponentUpdate` 方法,在 render 前判断是否有必要执行 render 提升性能。关于 React 声明周期,详情请参见官方文档:https://facebook.github.io/react/docs/react-component.html 。 + +附生命周期图: + +![lifecycle](https://img.alicdn.com/tps/TB1Ng7_MpXXXXamXFXXXXXXXXXX-2850-2945.jpg) + +## 总结 + +至此,几大 React 特性你大概了解了,再来回顾一下: + +* props 用来传递数据,state 用来存储组件内部的状态和数据。props 是只读的,state 当前组件 state 的值可以作为 props 传递给下层组件。 +* React 组件按照生命周期运行,改变 state 就会重新执行 render 方法。render 方法返回的是一段 JSX 语法的结构用来渲染到页面上。 diff --git a/docs/basis/use-component.md b/docs/basis/use-component.md new file mode 100644 index 0000000000..d74966c2c2 --- /dev/null +++ b/docs/basis/use-component.md @@ -0,0 +1,53 @@ +--- +title: 如何使用 ICE 组件 +category: 入门指引 +order: 6 +--- + +ICE 的组件统一使用 NPM 进行管理,所有的组件包都可以通过 npm 命令来安装。 + +## 检索组件 + +ICE 所有组件文档说明都部署在[物料 - 组件](https://alibaba.github.io/ice/#/components)上,同时你也可以在全局搜索框输入你想要的的组件名称进行查找。 + +## 安装与更新 + +ICE 基础组件在初始化项目时,已默认安装。这里主要讲解业务组件的安装与更新方法。 + +### 安装业务组件 + +在对应的业务组件文档上都有具体的安装和升级方法: + +#### 安装命令: + +```bash +npm install --save +``` + +#### 更新命令: + +```bash +npm install @latest --save +``` + +当需要更新项目内的组件的时,使用此命令 `@latest` 表示当装当前最新版本。也就达到升级组件的目的。 + +> 关于组件版本说明详见 + +## 使用组件 + +使用 `import from '';` 语句载入脚本,并定义为 `ComponentName` 。 + +> 对应组件文档下都有 DEMO 示例,可点击 查看源码 / 实时编辑 查看效果。 + +如: + +```jsx +import ReactDOM from 'react-dom'; +import IceTitle from '@icedesign/title'; + +// .... 省略其他代码 + +// 渲染 +ReactDOM.render(, mountNode) +``` diff --git a/docs/ice-design.md b/docs/ice-design.md new file mode 100644 index 0000000000..1889a1d20d --- /dev/null +++ b/docs/ice-design.md @@ -0,0 +1,93 @@ +--- +title: ICE 设计语言 +order: 2 +cover: https://gw.alicdn.com/tfs/TB1fcX1bkyWBuNjy0FpXXassXXa-1600-422.png +--- + +在淘宝内部,经过长时间调研和沉淀,我们产出了 ICE Design 这一套适合于中后台前端应用使用的设计语言。 +我们基于 ICE Design 开发了大量的可复用代码片段(区块),根据区块进行代码复用,大大节省开发时间,详情请见 [物料 - 区块](#/blocks)。 +脚手架初始模板简称为模板,我们针对实际场景的调研,提供了一批官方精选模板,实际效果请参见 [物料 - 模板](#/scaffolds)。在 [Iceworks](#/iceworks) 中生成项目选择对应脚手架即可。 + +## 升级背景 + +目前传统平台界面的设计语言存在着一些不足,比如色彩单一,大量线条的使用,分割化明显。其实,将这些不足归类一下就是界面单调,雷同性明显,缺少惊喜。也许新的平台类视觉风格可以打破这些束缚,尝试一些新的探索,启发传统的设计认知。因此,结合当下设计趋势,构思了一套新的平台产品设计语言。 + +### IDS 设计语言 + +![IDS 设计语言](https://gw.alicdn.com/tfs/TB1hT1ja1uSBuNjy1XcXXcYjFXa-2762-1040.png) + +### 设计手法 + +![设计手法](https://gw.alicdn.com/tfs/TB1TDWja1uSBuNjy1XcXXcYjFXa-2526-454.png) + +## 介绍 Introduction + +目前大部分的组件体系设计风格任然大同小异,ICE 为了突破现有的设计,尝试采用更激进的设计风格,比如沉浸式的导航设计,无分割的表格设计。新的设计语言除了遵循经典的设计定则,还汲取的最新的设计趋势,比如模块化投影化的处理方式,圆角的处理,更加突出内容的表现方式。 + +## 风格 Style + +### 色彩 + +色彩上相对于其他的组件风格,会将色彩更多的采用到组件和页面当中,避免传统的乏味、沉闷、冰冷的感觉。在合适的节点透出惊喜的感觉。此外增加了渐变的颜色,添加了质感,同时迎合当下流行的趋势。 + +![色彩](https://gw.alicdn.com/tfs/TB12IH9a_tYBeNjy1XdXXXXyVXa-2732-1900.png) + +同时提供了浅色版本和深色版本两个风格主题,在对氛围感有很强的要求的产品中可以尝试深色的主题。 + +![风格主题](https://gw.alicdn.com/tfs/TB1wUylaY9YBuNjy0FgXXcxcXXa-2328-824.png) + +### 字体排版 + +同时使用过多的字体尺寸和样式可以很轻易的毁掉布局。在字体的选择上,采用的是基础的并且适于阅读的字体字号,12、14、16、18、24 号字,并且他们能够良好的适应布局结构。这些尺寸和样式在经典应用场合中让内容密度和阅读舒适度取得平衡。 + +![字体](https://gw.alicdn.com/tfs/TB1hIH9a_tYBeNjy1XdXXXXyVXa-1490-1532.png) + +### 图像 + +在后台界面设计中,图像的用途几乎被忽视,然而图像有着建立情感联系,给人轻松愉悦感的作用。这些是 ICE 新的视觉风格里面需要的,因此,新的设计里加大了图像的透出比例。希望可以给用户更轻松的体验。 + +![图像](https://gw.alicdn.com/tfs/TB1NO09a3mTBuNjy1XbXXaMrVXa-2724-1970.jpg) + +## 基础设计原则 + +**接近原则** + +这样可以给用户一个直观的提示,越靠近的信息区块,关联性越大。接近原则是把信息按一定逻辑进行的“组队”。 + +**层次对比** + +页面上的信息通过组队后,一定会需要有侧重点,这时候对比的方法可以拉开内容之间的差距,从而凸显出页面的重点信息。层次对比是增加视觉效果的最直接的方式。 + +**对齐原则** + +如果页面上一些项是对齐的,就可以得到一个更内聚的单一,像是有一条看不见的线把信息排列的更整齐,即使元素可能在空间上间隔的很远,或不在一个“组队”里,对齐可以告诉用户他们之间还是存在某种联系。 + +**流程顺畅** + +中后台项目用户主要是进行信息查询或完成任务,所以相比前台项目注重页面的点击,在后台项目中路径顺畅要比点击次数更重要,甚至需要用越少的有效点击完成页面任务。流程顺畅可以快速提升用户对页面的好感度。 + +**简化认知** + +为了让用户准确有效的获取到页面的信息,就需要减少对信息元素的误解,简化认知成本,尽量让页面信息直白展现。中后台并不需要太多的“内涵丰富”的概念来呈现内容,准确表述功能减少认知负担。 + +## 预览效果图 + +### 首页预览效果 + +![](https://img.alicdn.com/tfs/TB1bPH0eiqAXuNjy1XdXXaYcVXa-1680-2502.jpg) + +### 表格 + +![](https://img.alicdn.com/tfs/TB1X6H0eiqAXuNjy1XdXXaYcVXa-1680-1953.jpg) + +### 列表页 + +![](https://img.alicdn.com/tfs/TB136D0eiqAXuNjy1XdXXaYcVXa-1680-1683.jpg) + +### Dashboard 页 + +![](https://img.alicdn.com/tfs/TB1U6D0eiqAXuNjy1XdXXaYcVXa-1680-2179.jpg) + +### 氛围增强版 + +![](https://img.alicdn.com/tfs/TB1b0yKgLDH8KJjy1XcXXcpdXXa-1680-1953.jpg) diff --git a/docs/iceworks.md b/docs/iceworks.md new file mode 100644 index 0000000000..9ade66a6fd --- /dev/null +++ b/docs/iceworks.md @@ -0,0 +1,139 @@ +--- +title: Iceworks 快速开始 +order: 3 +--- + +**零环境搭建** **零配置** **简单易用** + +Iceworks 是 ICE 推出的辅助开发者快速开发中后台前端应用的 GUI 软件,目前支持 macOS 和 Windows 两大平台。通过 [Iceworks](https://alibaba.github.io/ice/#/iceworks) 点击下载按钮即可。 + +## 创建项目 + +软件启动后,项目列表为空,可通过的【创建项目】新建一个项目。 + +![undefined | center](https://img.alicdn.com/tfs/TB1SKFucbGYBuNjy0FoXXciBFXa-1964-1424.png) + +界面会跳转到模板市场,目前提供三种模板进行选择,鼠标移动到指定的模板上,点击【以该模板创建项目】进入项目配置页面。 + +![undefined | center](https://img.alicdn.com/tfs/TB1MKBqcbGYBuNjy0FoXXciBFXa-1964-1424.png) + +* 新建一个文件夹或者选择已有的空文件夹(避免覆盖原有文件)。 +* 给项目起一个项目名,以便后续识别。 + +点击【开始创建项目】即可开始创建 + +> 默认会在创建的时候同时安装项目依赖,时间上会相对久一些,也可取消勾选,后续自行安装 + +## 管理项目 + +项目创建完成后,会自动添加到项目列表中,并打开当前项目管理面板。 + +通过项目管理面板,可执行 **启动调试服务** **新建页面** **构建项目** 等操作。 + +![undefined | center](https://img.alicdn.com/tfs/TB1VlrAcntYBeNjy1XdXXXXyVXa-1964-1424.png) + +## 启动调试服务 + +点击 `启动调试服务` 等待完成后出现服务地址,点击可以预览当前项目。 + +![undefined | center](https://img.alicdn.com/tfs/TB1p6lCceSSBuNjy0FlXXbBpVXa-2562-1590.png) + +> 上图是一个 ICE Design CMS 模板启动后的预览效果。 + +## 新建页面 + +启动调试服务后,可使用新建页面来搭建页面,通过 [block](https://alibaba.github.io/ice/#/template/block) 的组合完成页面的创建。 + +进入 block 搭建界面 + +![undefined | center](https://img.alicdn.com/tfs/TB14dBQch9YBuNjy0FfXXXIsVXa-1908-1368.png) + +上方列出了当前项目可用的 layout 布局方式,选中任一一个作为新页面的布局。 + +下方列出了当前可选择的 blocks, 点击即可选择该 block 到已选区块列表中。 + +右侧为选中 block 组合的缩略图预览。 + +选择 layout 以及 block 后,点击右下角生成页面,会提示输入页面名,路由名,可以定义需要的名称, + +* 页面名:表示生成的文件名称。 +* 路由名:表示页面的访问地址,可通过 `http://127.0.0.1:4444/#/xxxx` 访问到对应的路由页面。 + +示例中,创建了 `page16` 访问后即可看到刚搭建的页面了。 + +![undefined | center](https://img.alicdn.com/tfs/TB1jfVncbSYBuNjSspiXXXNzpXa-1964-1424.png) + +## 进入开发调试 + +点击项目版面上的 `编辑中打开` 会立即使用设置中选择的编辑器打开项目,目前支持 [Visual Studio Code](https://code.visualstudio.com/),[Sublime Text 3](https://www.sublimetext.com/),`WebStorm` 和 `Atom` 等编辑器,推荐使用 [Visual Studio Code](https://code.visualstudio.com/),如果你的电脑中未安装请先安装。 + +项目目录结构说明: + +``` +project-name +├── build // 打包资源 +├── mock // 模拟数据 +├── public // 静态资源 +├── src +│ ├── components // 公共组件 +│ ├── config // 公共配置 +│ ├── layouts // 通用布局 +│ ├── pages // 页面 +│ ├── utils // 通用方法 +│ ├── global.scss // 全局样式 +│ ├── index.html // 入口模板 +│ ├── index.js // 应用入口 +│ └── routes.jsx // 路由入口 +├── tests // 测试 +├── .editorconfig // 代码风格配置 +├── .eslintignore // eslint 忽略目录配置 +├── .eslintrc // eslint 配置 +├── generator.json // generator.json +├── package.json // package.json +├── README.md // 项目说明 +└── yarn.lock // 模板版本管理 +``` + +例如上一步已创建的 `Page16` 页面: + +![undefined | center](https://img.alicdn.com/tfs/TB1q6FtcbGYBuNjy0FoXXciBFXa-1968-1250.png) + +通过二次开发增加业务逻辑,完成业务需求。 + +## 打包发布 + +点击项目面板上的构建项目按钮,将开发的构建出最终的 js css 等资源。 + +构建完成后,会在项目目录下生成 `build` 文件夹,里面存在了 `index.html` `index.js` `index.css` 文件。使用你熟悉的方式,上传到对应的 cdn 服务器。 + +![undefined | center](https://img.alicdn.com/tfs/TB1TYpHckyWBuNjy0FpXXassXXa-1402-944.png) + +## 部署上线 + +上线过程即发布 HTML 文件的过程,`index.html` 文件存在在 `build` 目录中,将 `index.html` 文件复制到对应的服务服务器,并修改 html 源码中的 `/build/index.css` 和 `/build/index.js` 地址,是上一步中得到的 cdn 地址以及站点标题。 + +一个标准的 HTML 文件如下所示: + +```html + + + + + + + + + ICE Design CMS + + + +
+ + + + +``` + +> 在线上环境我们强烈推荐使用 production 版本的 React,而不是 development 版本。它们之间的区别除了体积之外,还包括一些针对线上环境的性能优化。 + +到这里你已经学会使用 Iceworks 创建一个项目并发布:) diff --git a/docs/materials/custom-react-materials.md b/docs/materials/custom-react-materials.md new file mode 100644 index 0000000000..d648b8b547 --- /dev/null +++ b/docs/materials/custom-react-materials.md @@ -0,0 +1,254 @@ +--- +title: 自定义 React 物料 +order: 3 +category: 物料 +--- + +## 基础规范 + +* 区块名称: 大驼峰写法, 如 `ExampleBlock`, 遵循简练能表达组件含义的原则 +* 基础编码码规范: [JavaScript Style Guide](https://github.com/airbnb/javascript) +* CSS 规范: [CSS-in-JS](https://github.com/MicheleBertoli/css-in-js) + +## 初始 React 物料项目 + +使用 `ice-devtools init` 选择初始类型是 React,按照提示依次输入初始信息: + +``` +$ ice-devtools init ice-materials-template app +? 选择初始类型 +❯ ◯ React + ◯ Vue +? 项目名称 +? 项目描述 +``` + +创建完成后会生成如下目录结构,包含区块、布局、脚手架模板三个目录,在对应的目录下面默认内置一个相对应的示例: + +``` +ice-materials-template +├── react-materials +│ ├── blocks // 区块 +│ │ └── ExampleBlock +│ ├── layouts // 布局 +│ │ └── ExampleLayout +│ └── scaffolds // 脚手架模板 +│ │ └── ice-app +├── .editorconfig +├── .eslintignore +├── .eslintrc +├── .gitignore +├── .prettierignore +├── .prettierrc +├── LICENSE +├── README.md +├── lerna.json +└── package.json +``` + +## 启动本地服务 + +初始化完成后,可以通过 `ice-devtools start` 启动本地服务,可以看到初始的区块,布局列表: + +``` +$ ice-devtools start +``` + +**预览界面** +![ice-materials-preview](https://img.alicdn.com/tfs/TB15cl2lSBYBeNjy0FeXXbnmFXa-2786-1524.png) + +## 自定义区块 + +### 区块分类 + +区块主要按照中后台业务常见的功能类型进行分类,不同的分类对应不同的区块,分类如下: + +* 登录页 +* 欢迎页 +* 表格 +* 列表 +* 表单 +* 图表 +* 异常 +* 筛选 +* 视频 +* 模态框 +* 数据展示 +* 信息展示 + +### 添加区块 + +进入初始化的项目,使用 `ice-devtools add` 添加区块,添加流程的规则如下: + +* 初始项目选择 react 类型,默认添加到 react 对应的 react-materials/blocks 物料目录下 +* 初始项目选择 vue 类型,默认添加到 vue 对应的 vue-materials/blocks 物料目录下 +* 初始项目同时选择 react、vue,添加物料的时候将会询问添加物料的类型,同时生成到对应的物料目录下 + +``` +➜ cd your-project +➜ ice-devtools add +? 选择添加类型 (Use arrow keys) +❯ 区块 + 布局 + 模板 +``` + +根据提示输入对应的区块信息,添加完成后会在 `your-project/react-materials/blocks/` 目录下新增一个区块,目录结构如下: + +``` +. +└── ExampleBlock + ├── README.md // 说明文档 + ├── package.json // pkg.json + └── src // source 源码目录 + ├── ExampleBlock.jsx + └── index.js // 模块入口 +``` + +### 目录文件说明 + +**src/ExampleBlock.jsx** + +`ExampleBlock.jsx` 文件提供了基础的区块模板代码规范,方便快速开发一个区块: + +```jsx +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; + +export default class ExampleBlock extends Component { + static displayName = 'ExampleBlock'; + + static propTypes = { + value: PropTypes.string, + }; + + static defaultProps = { + value: 'string data', + }; + + constructor(props) { + super(props); + this.state = {}; + } + + render() { + return
example-block
; + } +} + +const styles = {}; +``` + +**src/index.js** + +区块的入口文件,导出当前区块 + +``` +import ExampleBlock from './ExampleBlock'; + +export default ExampleBlock; +``` + +**package.json** + +`package.json` 的 `blockConfig` 字段描述了区块的名称,截图,标题,分类等信息,主要用于 Iceworks 展示使用,在创建区块时自动生成,但截图需要在区块开发完成后录入。 + +``` +{ + "name": "example-block", // npm 包名 + "version": "1.0.0", + "description": "", // 区块描述 + "author": "", + "files": [ + "src/", + "lib/" + ], + "dependencies": { + "react": "^16.3.0", + }, + "blockConfig": { // 区块的相关配置,用于 Iceworks 和站点的展示 + "name": "example-block", // 名称 + "screenshot": "", // 截图 + "title": "示例区块", // 标题 + "categories": "[]" // 分类 + } +} +``` + +**README.md** +说明文档主要包含区块名,区块简介,以及区块截图三个字段信息 + +``` +# example-block + +简介:示例区块 + +![截图]() +``` + +### 开发调试 + +新增一个区块后,可以看到通过 `ice-devtools start` 启动的浏览器窗口看到新增的区块,支持实时编译和监听改动。 + +## 自定义布局 + +布局与区块在开发模式上基本保持相同,不同点在于布局没有分类的概念,可以根据业务需求和设计规范自定义不同的布局。 + +## 自定义脚手架 + +### 添加模板 + +在生成的项目中默认内置了一个模板示例,你可以基于该模板进行开发,也可以通过命令 `ice-devtools add` 时选择模板进行添加: + +``` +$ ice-devtools add +? 选择添加类型 (Use arrow keys) + 区块 + 布局 +❯ 模板 +``` + +初始化完成会生成如下目录结构: + +``` +. +├── mock // 模拟数据 +├── public // 静态资源 +├── src +│ ├── components // 公共组件 +│ ├── layouts // 通用布局 +│ ├── pages // 页面 +│ ├── index.js // 应用入口 +│ ├── menuConfig // 导航配置 +│ ├── routerConfig // 路由配置 +│ └── router.jsx // 路由入口 +├── tests // 测试 +├── .gitignore // git 忽略目录配置 +├── .editorconfig // 代码风格配置 +├── .eslintignore // eslint 忽略目录配置 +├── .eslintrc // eslint 配置 +├── package.json // package.json +└── README.md // 项目说明 +``` + +### 开发调试 + +脚手架的开发调试与常规项目开发模式相同: + +``` +$ cd your-scaffold +$ npm run start // 启动服务 +$ npm run build // 构建项目 +``` + +## 发布 + +当物料开发完成时,需要生成静态的物料数据,发布到 CDN 或者其他可访问的在线地址提供给 Iceworks 使用,命令如下 + +``` +$ npm run bootstrap // 初始 lerna +$ npm run publish // 发布 NPM 包 +$ npm run db // 生成 DB 数据 +``` + +接入 Iceworks 流程与自定义 Vue 物料开发接入流程一致,具体请参考 `自定义 Vue 物料` 接入 Iceworks 流程部分。 diff --git a/docs/materials/custom-vue-materials.md b/docs/materials/custom-vue-materials.md new file mode 100644 index 0000000000..70ad2dffc5 --- /dev/null +++ b/docs/materials/custom-vue-materials.md @@ -0,0 +1,310 @@ +--- +title: 自定义 Vue 物料 +order: 4 +category: 物料 +--- + +## 基础规范 + +* 区块名称: 大驼峰写法, 如 `ExampleBlock`, 遵循简练能表达组件含义的原则 +* 基础编码码规范: [JavaScript Style Guide](https://github.com/airbnb/javascript) +* CSS 规范: [CSS-in-JS](https://github.com/MicheleBertoli/css-in-js) + +## 安装物料开发工具 + +执行 `npm install ice-devtools -g` + +## 初始 Vue 物料项目 + +使用 `ice-devtools init` 开始进入环境生成操作,按照提示依次输入初始信息: + +``` +$ ice-devtools init ice-materials-template app +? 选择初始类型 + ◯ React +❯ ◯ Vue +? 项目名称 +? 项目描述 +``` + +创建完成后会生成如下目录结构,包含区块、布局、脚手架模板三个目录,在对应的目录下面默认内置一个相对应的示例: + +``` +ice-materials-template +├── vue-materials +│ ├── blocks // 区块 +│ │ └── ExampleBlock +│ ├── layouts // 布局 +│ │ └── ExampleLayout +│ └── scaffolds // 脚手架模板 +│ │ └── ice-app +├── .editorconfig +├── .eslintignore +├── .eslintrc +├── .gitignore +├── .prettierignore +├── .prettierrc +├── LICENSE +├── README.md +├── lerna.json +└── package.json +``` + +## 启动本地服务 + +初始化完成后,可以通过 `ice-devtools start` 启动本地服务,可以看到初始的区块,布局列表: + +``` +$ ice-devtools start +``` + +**预览界面(todo 目前 beta 阶段只有简版)** +![ice-materials-preview](https://img.alicdn.com/tfs/TB15cl2lSBYBeNjy0FeXXbnmFXa-2786-1524.png) + +## 自定义区块 + +### 区块分类 + +区块主要按照中后台业务常见的功能类型进行分类,不同的分类对应不同的区块,分类如下: + +* 登录页 +* 欢迎页 +* 表格 +* 列表 +* 表单 +* 图表 +* 异常 +* 筛选 +* 视频 +* 模态框 +* 数据展示 +* 信息展示 + +### 添加区块 + +进入初始化的项目,使用 `ice-devtools add` 添加区块,添加流程的规则如下: + +* 初始项目选择 react 类型,默认添加到 react 对应的 react-materials/blocks 物料目录下 +* 初始项目选择 vue 类型,默认添加到 vue 对应的 vue-materials/blocks 物料目录下 +* 初始项目同时选择 react、vue,添加物料的时候将会询问添加物料的类型,同时生成到对应的物料目录下 + +``` +➜ cd your-project +➜ ice-devtools add +? 选择添加类型 (Use arrow keys) +❯ 区块 + 布局 + 模板 +``` + +根据提示输入对应的区块信息,添加完成后会在 `your-project/vue-materials/blocks/` 目录下新增一个区块,目录结构如下: + +``` +. +└── ExampleBlock + ├── README.md // 说明文档 + ├── package.json // pkg.json + └── src // source 源码目录 + ├── ExampleBlock.vue + └── index.js // 模块入口 +``` + +### 目录文件说明 + +**src/ExampleBlock.vue** + +`ExampleBlock.vue` 文件提供了基础的区块模板代码规范,方便快速开发一个区块: + +``` + + + + + +``` + +**src/index.js** + +区块的入口文件,导出当前区块 + +``` +import ExampleBlock from './ExampleBlock'; + +export default ExampleBlock; +``` + +**package.json** + +`package.json` 的 `blockConfig` 字段描述了区块的名称,截图,标题,分类等信息,主要用于 Iceworks 展示使用,在创建区块时自动生成,但截图需要在区块开发完成后录入。 + +``` +{ + "name": "example-block", // npm 包名 + "version": "1.0.0", + "description": "", // 区块描述 + "author": "", + "files": [ + "src/", + "lib/" + ], + "dependencies": { + "vue": "^2.5.16" + }, + "blockConfig": { // 区块的相关配置,用于 Iceworks 和站点的展示 + "name": "example-block", // 名称 + "screenshot": "", // 截图(如果没有截图则不在 Iceworks 中显示图片) + "title": "示例区块", // 标题 + "categories": "[]" // 分类 + } +} +``` + +**README.md** +说明文档主要包含区块名,区块简介,以及区块截图三个字段信息 + +``` +# example-block + +简介:示例区块 + +![截图]() +``` + +### 开发调试 + +新增一个区块后,可以看到通过 `ice-devtools start` 启动的开发者界面刷新看到新增的区块,支持实时编译和监听改动。 + +## 自定义布局 + +布局与区块在开发模式上基本保持相同,不同点在于布局没有分类的概念,可以根据业务需求和设计规范自定义不同的布局。 + +## 自定义脚手架 + +### 添加模板 + +在生成的项目中默认内置了一个模板示例,你可以基于该模板进行开发,也可以通过命令 `ice-devtools add` 时选择模板进行添加: + +``` +$ ice-devtools add +? 选择添加类型 (Use arrow keys) + 区块 + 布局 +❯ 模板 +``` + +初始化完成会生成如下目录结构: + +``` +. +├── README.md +├── package.json +├── public +│   ├── favicon.ico +│   └── index.html +├── src +│   ├── App.vue +│   ├── assets +│   │   └── logo.png +│   ├── components +│   │   └── HelloWorld.vue +│   ├── layouts +│   │   └── BlankLayout +│   │   └── index.vue +│   ├── main.js +│   ├── pages +│   │   ├── About +│   │   │   ├── About.vue +│   │   │   └── index.js +│   │   └── Home +│   │   ├── Home.vue +│   │   └── index.js +│   └── router.js +└── vue.config.js +``` + +### 开发调试 + +脚手架就是用户生成到项目中的初始文件、目录,脚手架的开发调试与常规项目开发模式相同: + +``` +$ cd your-scaffold +$ npm run start // 启动服务 +$ npm run build // 构建项目 +``` + +Iceworks 对于脚手架会将其直接下载解压到目录中。 + +## 发布 + +当物料开发完成时,发布需要几个步骤: + +1. 清理无用代码。默认生成的 example-block 等需要删除,因为它们的 package name 已经被占用无法发布。 +2. 将物料以 npm 包的形式发布。Iceworks 将通过 npm 下载物料解压使用。 +3. 生成物料源 db.json。根据你当前的物料生成 db 的数据,提供给 iceworks 使用。 +4. 部署 db.json 到 http 静态服务器,将 url 发送给使用者填入 iceworks 即可开始使用。 + +> 建议:模板 + 布局 + 模块 为一套完整的工程物料,建议发布之前保证每一类都有一个物料。 + +相关命令如下: + +通过 lerna 发布物料包: + +``` +$ npm run bootstrap // 初始 lerna +$ npm run publish // 发布 NPM 包 +``` + +lerna 批量发包会比较容易,但可能会出现一些异常。而且 lerna 的变更检测是通过 git tag 实现的,因此通过这种方式你必须创建一个 git 仓库在 github 或者 gitlab 等。 + +其实只要将物料发包即可,因此你也可以选择普通的 npm 命令的方式发布,只是这样操作步骤会变多一些: + +``` +$ cd 到对应物料目录 +$ npm publish +``` + +之后生成物料 DB: + +``` +$ ice-devtools generate // 生成 DB 数据 +``` + +此时将会在当前物料源下面新建 `build` 目录,并生成 json 文件。 + +创建一个 http 静态服务器托管这个 db.json。你可以使用 https://browsersync.io/ 或者 python SimpleHTTPServer 等启动静态服务,并可以通过类似 `http://localhost:3000/vue-materials.json` 这样的方式获取到物料数据。 + +至此,物料源开发完成,可以在 Iceworks 中试用。 + +## 接入 Iceworks + +目前还在 beta 版本,支持多物料源的 Iceworks 并没有正式发布,详情请参见群里。 + +在设置面板中填入当前物料源 db url: + +![](https://img.alicdn.com/tfs/TB1qYBFnMmTBuNjy1XbXXaMrVXa-1736-1150.png) + +之后在创建项目界面即可看到你的自定义物料: + +![](https://img.alicdn.com/tfs/TB10ONGnQOWBuNjSsppXXXPgpXa-1740-1152.png) diff --git a/docs/materials/data-specification.md b/docs/materials/data-specification.md new file mode 100644 index 0000000000..aeab5e50ea --- /dev/null +++ b/docs/materials/data-specification.md @@ -0,0 +1,164 @@ +--- +title: 物料数据规范 +order: 6 +category: 物料 +--- + +## 飞冰设计思路 + +在了解飞冰物料数据规范之前,我们先来大概了解一下飞冰的设计思路;在飞冰使用过程中,大多数开发者只需要下载 GUI 工具 Iceworks,然后按照文档教程进行项目开发即可。目前飞冰提供的物料数据源有 React 和 Vue 版本,然而,在飞冰开发群里常见的问题是有没有计划支持 AngularJS 版本,有没有移动端的支持计划等等。实际上,对飞冰来说,本质上一套通用的模式,只需要按照相应的数据规范生产物料、生成数据源,最后通过 Iceworks 接入即可。如果你计划接入一套新的框架物料,可以参考下面的步骤进行: + +![material-flow](https://img.alicdn.com/tfs/TB1KgToqN9YBuNjy0FfXXXIsVXa-2014-1326.png) + +**选定物料类型和开发规范** + +前面讲到,对飞冰来讲本质上是通过一套通用的数据协议结合 Iceworks 运作的,因此,选定物料类型你可以基于 React、Vue、Angular 甚至是 Bootstrap 进行开发。 + +开发规范主要是指开发物料时的编码规范,比如 `HTML`、`CSS`、 `JavaScript` 等基础规范。 + +**物料脚手架** + +物料主要包括组件、区块、布局、模板,在开发物料时,我们需要按照一定的模板代码进行开发,因此需要先规划好物料类型以及对应的物料脚手架。详细可参考 [React 和 Vue 物料脚手架](https://github.com/alibaba/ice/tree/master/templates) + +**开发者工具** + +开发者工具主要包含`项目构建工具`和`物料开发工具`,项目构建工具故名思议是用来启动,构建项目的,比如我们为飞冰项目提供的项目构建工具 [ice-scripts](https://github.com/alibaba/ice/tree/master/tools/ice-scripts)。大家在使用 Iceworks 时,会经常用到 Iceworks 项目面板的 **启动调试服务**、**构建项目** 等功能,其背后的原理本质上是通过 GUI 的形式去调用了 CLI 的命令. + +项目是可以脱离 Iceworks 单独运行的,`package.json` 里声明 `scripts` 命令,必须存在 `start` `build`. 通过 `npm run start` 与 `npm run build` 即可启动调试服务与构建。 + +Iceworks 会识别项目中定义的 `scripts` 脚本,**启动调试服务**、**构建项目** 分别对应 `npm run start` `npm run build`。当然,你不一定要自己去实现一个完整的 CLI 工具,Vue 社区已经有了很完善的工具 [vue-cli](https://github.com/vuejs/vue-cli),AngularJs 也有对应的 [angular-cli](https://github.com/angular/angular-cli)。 + +物料开发工具即为开发物料提供的配套工具,物料开发工具提供的能力主要是根据预设好的物料脚手架进行初始化,生成模板文件方便开发,同时提供预览,热加载等服务。详细可参考 [飞冰物料开发工具 ice-devtools](https://github.com/alibaba/ice/tree/master/tools/ice-devtools) + +**生成物料数据** + +在物料开发完成时,需要生成对应的物料元数据,为 Iceworks 提供数据源。数据源为一份 JSON 文件。 + +> 可参考 + +**接入 Iceworks** + +生成好物料数据源,只需要将物料数据源发布 CDN 提供给 Iceworks, 在设置面板中添加即完成了完整链路的闭环。 + +## 物料数据规范 + +飞冰`物料数据规范`是一套通用的描述物料的元数据的标准格式,规范约定了物料的类型、名称、版本、数据源、存储位置等信息。目前基于飞冰物料数据规范实现了 [vue-materials](https://g.alicdn.com/ice-assets/ice-design/databases/vue-materials.json) 和 [react-materials](https://g.alicdn.com/ice-assets/ice-design/databases/react-materials.json) 两个版本的物料数据源。 + +**数据规范** + +``` +{ + "name": "react-materials", // 名称 + "type": "react", // 类型(vue、react、angular、bootstrap、etc) + "blocks": [], // 区块元数据 + "layouts": [], // 布局元数据 + "scaffolds": [] // 模板脚手架元数据 +} +``` + +**区块规范说明** + +``` +{ + // (必)英文名 + "name": "application-progress", + + // (必)中文描述 + "title": "申请进度信息展示", + + // (可)区块详细说明 + "description": "", + + // (必) source 字段描述区块下载方式 + "source": { + "type": "npm", + "npm": "@icedesign/foo-block", + "version": "0.1.0", + "sourceCodeDirectory": "src", + }, + + // (必) 分类 + "categories": ["信息展示"], + + // (必) 截图 + "screenshot": "https://img.alicdn.com/tfs/TB1I67ih3vD8KJjy0FlXXagBFXa-947-929.png", + + // (必) 发布时间 + "publishTime": "2018-03-13 22:19", + + // (必) 最后修改时间 + "updateTime": "2018-03-13 22:19", + + // (必) 用于说明组件依赖关系 + "components": { + "@icedesign/base": "^x.x.x", + }, + + // (可) 保留字段 + "features": { + // 分词, 用于搜索 + "participle": { /* ... */ }, + } +} +``` + +**区块规范说明** + +布局规范与区块类似,但需要增加一个 `thumbnail` 用来指定抽象缩略图,用在 iceworks 的新建页面流程中,用来选择布局 + +``` +... +"thumbnail": "https://gw.alicdn.com/tfs/TB172QmlsLJ8KJjy0FnXXcFDpXa-976-974.png" +... +``` + +**模板规范说明** + +``` +{ + // (必)英文名 + "name": "ice-design-pro", + + // (必)中文描述 + "title": "pro 模板", + + // (可)区块详细说明 + "description": "", + + // (可)模板预览地址 + "homepage": "https://alibaba.github.io/ice/scaffold-preview/ice-design-pro.html" + + // (必) source 字段描述下载方式, 下详 + "source": { + "type": "npm", + "npm": "@icedesign/foo-block", + "version": "0.1.5", + "sourceCodeDirectory": "src", + }, + + // (可) 分类 + "categories": [], + + // (必) 截图 +  "screenshot": "https://img.alicdn.com/tfs/TB1I67ih3vD8KJjy0FlXXagBFXa-947-929.png", + + // (必) 发布时间 + "publishTime": "2018-03-13 22:19", + + // (必) 最后修改时间 + "updateTime": "2018-03-13 22:19", + + // (必) 用于说明组件依赖关系 (dependencies 字段) + "components": { + "@icedesign/base": "^x.x.x", + }, + + // (可) 保留字段 + "features": { + // 分词, 用于搜索 + "participle": { /* ... */ }, + } +} +``` + +至此,我们对飞冰的设计思想和物料数据规范有了大概的了解,如何自定义一套物料接入 Iceworks 的流程。如果你看完还是不知道如何开始动手,可以通过飞冰钉钉群联系我们。 diff --git a/docs/materials/how-to-contribute.md b/docs/materials/how-to-contribute.md new file mode 100644 index 0000000000..6831abc498 --- /dev/null +++ b/docs/materials/how-to-contribute.md @@ -0,0 +1,225 @@ +--- +title: 如何贡献 +order: 5 +category: 物料 +--- + +目前飞冰提供了基于 React 技术栈的物料,React 物料由飞冰团队维护,每周会定期更新。但在飞冰的用户群里,我们收到很多反馈,希望能提供对 Vue 的支持,为此,我们提供了开发者工具 ice-devtools,以及基础的 Vue 物料。当然,这对于物料体系来说,所做的远远不够,如果你热爱开源,欢迎与我们一起共同建设。 + +## 环境准备 + +``` +// 安装开发者工具 ice-devtools +$ npm i ice-devtools -g + +// clone 官方仓库 +$ git clone git@github.com:alibaba/ice.git +$ npm run bootstrap +$ npm run start +``` + +通过上面的命令可以启动服务,支持预览 react-materials 和 vue-materials 目录下的所有区块和布局,启动主界面如下,可通过点击物料类型选择预览不同的物料。 + +![](https://img.alicdn.com/tfs/TB17haCnKuSBuNjy1XcXXcYjFXa-2858-1586.png) + +## 开发区块 + +以开发 Vue 物料为例添加一个区块,首先进入 ice 项目目录,通过 `ice-devtools add` 命令选择需要添加的物料类型,根据提示输入对应的信息,添加完成后会在 `ice/vue-materials` 目录下新增对应的模板文件。 + +``` +$ cd ice +$ ice-devtools add + ? 选择添加类型 (Use arrow keys) + ❯ 区块 + 布局 + 模板 +``` + +目录结构如下: + +``` +. +└── ExampleBlock + ├── README.md // 说明文档 + ├── package.json // pkg.json + └── src // source 源码目录 + ├── ExampleBlock.vue + └── index.js // 模块入口 +``` + +## 目录文件说明 + +**src/ExampleBlock.vue** + +`ExampleBlock.vue` 文件提供了基础的区块模板代码规范,方便快速开发一个区块: + +``` + + + + + +``` + +**src/index.js** + +区块的入口文件,导出当前区块 + +``` +import ExampleBlock from './ExampleBlock'; + +export default ExampleBlock; +``` + +**package.json** + +`package.json` 的 `blockConfig` 字段描述了区块的名称,截图,标题,分类等信息,主要用于 Iceworks 展示使用,在创建区块时自动生成,但截图需要在区块开发完成后补充录入。 + +``` +{ + "name": "example-block", // npm 包名 + "version": "1.0.0", + "description": "", // 区块描述 + "author": "", + "files": [ + "src/", + "lib/" + ], + "dependencies": { + "vue": "^2.5.16", + "@vue-materials/basic-container": "^1.0.0", + }, + "blockConfig": { // 区块的相关配置,用于 Iceworks 和站点的展示 + "name": "example-block", // 名称 + "screenshot": "", // 截图(如果没有截图则不在 Iceworks 中显示图片) + "title": "示例区块", // 标题 + "categories": "[]" // 分类 + } +} +``` + +**README.md** +说明文档主要包含区块名,区块简介,以及区块截图三个字段信息 + +``` +# example-block + +简介:示例区块 + +![截图]() +``` + +## 添加布局 + +布局与区块在开发模式上基本保持相同,不同点在于布局没有分类的概念,可以根据业务需求和设计规范自定义不同的布局。 + +## 开发调试 + +新增一个区块后,在主界面物料类型选择 vue-materials 进入物料列表页面如下: + +![](https://img.alicdn.com/tfs/TB1TP3InTtYBeNjy1XdXXXXyVXa-2864-1474.png) + +在列表页面,已经有了一些基础的区块和布局,可以点击预览查看效果图,支持实时编译刷新调试。 + +## 提交代码 + +### 提交 Pull Request + +如果你准备贡献代码,那么你可以创建分支修改代码提交 PR,飞冰开发团队会 review 代码合并到主干。 + +```bash +# 先创建开发分支开发,分支名应该有含义,避免使用 update、tmp 之类的 +$ git checkout -b branch-name + +# 开发完成后可以运行 lint 检查语法 +$ npm run lint + +# 提交代码,message 见下面的规范 +$ git add . # git add -u 删除文件 +$ git commit -m "fix: add xxx block" +$ git push origin branch-name +``` + +提交后就可以在 [ice](https://github.com/alibaba/ice/pulls) 创建 Pull Request 了。 + +### 代码风格 + +你的代码风格必须通过 eslint,你可以运行 `$ npm run lint` 本地测试。 + +### Commit 提交规范 + +根据 [angular 规范](https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md#commit-message-format)提交 commit,这样 history 看起来更加清晰,还可以自动生成 changelog。 + +```xml +(): + + + +