├── .eslintignore ├── .eslintrc.js ├── .github ├── FUNDING.yml ├── release-drafter.yml └── workflows │ ├── eb-docs.yml │ └── eb-release.yml ├── .gitignore ├── .npmrc ├── LICENSE ├── README.cn.md ├── README.md ├── global.d.ts ├── lerna.json ├── package.json ├── packages ├── client-core │ ├── .npmignore │ ├── LICENSE │ ├── README.md │ ├── package.json │ └── src │ │ ├── branch │ │ ├── branch-block.ts │ │ ├── cache.ts │ │ ├── if.ts │ │ └── switch.ts │ │ ├── context.ts │ │ ├── element │ │ ├── alins.d.ts │ │ ├── attributes.ts │ │ ├── class.ts │ │ ├── component.ts │ │ ├── custom-renderer.ts │ │ ├── dom-util.ts │ │ ├── element.ts │ │ ├── event.ts │ │ ├── jsx.d.ts │ │ ├── lifecycle.ts │ │ ├── model.ts │ │ ├── renderer.ts │ │ └── style.ts │ │ ├── for.ts │ │ ├── index.ts │ │ └── utils.ts ├── client-reactive │ ├── .npmignore │ ├── LICENSE │ ├── README.md │ ├── package.json │ └── src │ │ ├── array-proxy.ts │ │ ├── cleaner.ts │ │ ├── computed.ts │ │ ├── extends.ts │ │ ├── index.ts │ │ ├── proxy.ts │ │ ├── reactive.ts │ │ ├── store.ts │ │ └── watch.ts ├── client-standalone │ ├── .npmignore │ ├── LICENSE │ ├── README.md │ ├── package.json │ └── src │ │ └── index.ts ├── client-utils │ ├── .npmignore │ ├── LICENSE │ ├── README.md │ ├── package.json │ └── src │ │ ├── index.ts │ │ ├── types │ │ ├── common.d.ts │ │ ├── enum.ts │ │ ├── react.d.ts │ │ └── symbol.ts │ │ └── utils.ts ├── compiler-core │ ├── .npmignore │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── pnpm-lock.yaml │ └── src │ │ ├── comment.ts │ │ ├── component │ │ ├── component.ts │ │ └── logic-attribute.ts │ │ ├── context.ts │ │ ├── controller │ │ ├── control-scope.ts │ │ ├── func-reactive.ts │ │ ├── if-scope.ts │ │ ├── import-manager.ts │ │ ├── jsx-scope.ts │ │ ├── map.ts │ │ ├── scope-stack.ts │ │ ├── static-scope.ts │ │ └── switch-scope.ts │ │ ├── index.ts │ │ ├── is.ts │ │ ├── parse-utils.ts │ │ ├── scope.ts │ │ ├── transform.ts │ │ └── types.d.ts ├── compiler-node │ ├── .npmignore │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── pnpm-lock.yaml │ └── src │ │ ├── extend.d.ts │ │ └── index.ts ├── compiler-web │ ├── .npmignore │ ├── LICENSE │ ├── README.md │ ├── package.json │ └── src │ │ ├── babel.min.d.ts │ │ ├── babel.min.js │ │ ├── boot.ts │ │ ├── index.ts │ │ ├── parser.ts │ │ └── test.tsx ├── plugin-babel-preset │ ├── .npmignore │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── pnpm-lock.yaml │ └── src │ │ └── index.ts ├── plugin-babel │ ├── .npmignore │ ├── LICENSE │ ├── README.md │ ├── package.json │ └── src │ │ └── index.ts ├── plugin-esbuild │ ├── .npmignore │ ├── LICENSE │ ├── README.md │ ├── package.json │ └── src │ │ └── index.ts ├── plugin-eslint │ ├── .npmignore │ ├── LICENSE │ ├── README.md │ ├── index.js │ ├── package.json │ ├── pnpm-lock.yaml │ └── ts.js ├── plugin-rollup │ ├── .npmignore │ ├── LICENSE │ ├── README.md │ ├── package.json │ └── src │ │ └── index.ts ├── plugin-vite │ ├── .npmignore │ ├── LICENSE │ ├── README.md │ ├── package.json │ └── src │ │ └── index.ts └── plugin-webpack │ ├── .npmignore │ ├── LICENSE │ ├── README.md │ ├── package.json │ └── src │ └── index.ts ├── pnpm-lock.yaml ├── scripts ├── .DS_Store ├── a.html ├── build │ ├── babel.config.js │ ├── build-multi.js │ ├── build.js │ ├── export-assign.js │ ├── mod-package.js │ ├── rollup.config.js │ ├── style-all-cdn.ts │ └── utils.js ├── clear-dist.js ├── dev.js ├── dev │ ├── data.js │ ├── dev-node.ts │ ├── dev-web-compiler.ts │ ├── dev-web-standalone.ts │ ├── index.html │ ├── samples-list.ts │ └── samples │ │ ├── bench.jsx │ │ ├── canvas-renderer.jsx │ │ ├── data.js │ │ ├── define-renderer.jsx │ │ ├── define-renderer.tsx │ │ ├── demo.js │ │ ├── if-sample.tsx │ │ ├── increment.tsx │ │ ├── list.tsx │ │ ├── playground.jsx │ │ ├── rfc.html │ │ ├── style-reactive.jsx │ │ ├── template-rfc.html │ │ ├── todo-list.tsx │ │ ├── use-renderer.jsx │ │ └── vjsx.tsx ├── feature.todo ├── helper │ ├── .npmignore │ ├── README_DEV.md │ ├── dependent-graph.json │ ├── docs │ │ ├── code.jpg │ │ ├── dev.md │ │ ├── output.jpg │ │ └── performance.jpg │ ├── packages-info.json │ ├── qa.md │ ├── utils.js │ └── version.md ├── info.js ├── init-learn-dep.js ├── init-packages-info.js ├── lerna-add.txt ├── playground │ ├── babel-preset │ │ ├── babel.config.json │ │ ├── dev │ │ │ ├── alins.min.js │ │ │ ├── bundle.js │ │ │ ├── copy-alins.js │ │ │ └── index.html │ │ ├── package.json │ │ ├── pnpm-lock.yaml │ │ └── src │ │ │ └── alins.tsx │ ├── babel │ │ ├── babel.config.json │ │ ├── dev │ │ │ ├── alins.min.js │ │ │ ├── bundle.js │ │ │ ├── copy-alins.js │ │ │ └── index.html │ │ ├── package.json │ │ ├── pnpm-lock.yaml │ │ └── src │ │ │ └── alins.tsx │ ├── compare │ │ └── react │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── pnpm-lock.yaml │ │ │ ├── src │ │ │ ├── count.jsx │ │ │ └── main.jsx │ │ │ └── webpack.config.js │ ├── esbuild │ │ ├── dev │ │ │ ├── bundle.js │ │ │ ├── dev.js │ │ │ └── index.html │ │ ├── package.json │ │ ├── pnpm-lock.yaml │ │ └── src │ │ │ ├── alins.tsx │ │ │ └── index.ts │ ├── rollup │ │ ├── dev │ │ │ ├── alins.tsx │ │ │ ├── bundle.js │ │ │ ├── index.html │ │ │ └── rollup.js │ │ ├── package.json │ │ └── pnpm-lock.yaml │ ├── vite │ │ ├── index.html │ │ ├── package.json │ │ ├── pnpm-lock.yaml │ │ ├── public │ │ │ └── vite.svg │ │ ├── src │ │ │ ├── alins.tsx │ │ │ ├── main.ts │ │ │ └── vite-env.d.ts │ │ ├── test.html │ │ ├── tsconfig.json │ │ └── vite.config.ts │ └── webpack │ │ ├── dev │ │ ├── bundle.js │ │ └── index.html │ │ ├── package.json │ │ ├── pnpm-lock.yaml │ │ ├── src │ │ ├── alins.tsx │ │ └── index.ts │ │ ├── tsconfig.json │ │ └── webpack.config.js ├── purge-cdn.js ├── push-release.js ├── test.js ├── test │ ├── bugs.tsx │ ├── client │ │ ├── cases │ │ │ ├── async.tsx │ │ │ ├── dom.tsx │ │ │ ├── for.tsx │ │ │ ├── if.tsx │ │ │ ├── props.tsx │ │ │ ├── reactive.ts │ │ │ └── switch.tsx │ │ └── index.ts │ ├── compiler │ │ ├── compiler-base.ts │ │ ├── compiler-cases │ │ │ ├── async.ts │ │ │ ├── if.ts │ │ │ ├── jsx.ts │ │ │ ├── map.ts │ │ │ ├── mix.ts │ │ │ ├── props.ts │ │ │ ├── react.ts │ │ │ ├── switch.ts │ │ │ └── test.ts │ │ ├── node.ts │ │ ├── util.ts │ │ └── web.ts │ ├── demos.tsx │ └── test-util.tsx ├── v1-parser.js ├── version.en.md └── version.md └── tsconfig.json /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | scripts/dev/*.js 3 | *.html 4 | **/libs/*.js 5 | dist 6 | cdn 7 | *.min.js -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: tackchen 3 | * @Date: 2022-09-04 08:02:56 4 | * @Description: Coding something 5 | */ 6 | module.exports = { 7 | parser: '@typescript-eslint/parser', 8 | plugins: [ 9 | '@typescript-eslint', 10 | ], 11 | 'env': { 12 | 'node': true, 13 | }, 14 | rules: { 15 | 'no-var': 'error', 16 | 'no-extend-native': 0, 17 | 'no-new': 0, 18 | 'no-useless-escape': 0, 19 | 'no-useless-constructor': 0, 20 | 'no-trailing-spaces': [ 'error', { 'skipBlankLines': true } ], 21 | 'indent': [ 'error', 4, { 22 | 'SwitchCase': 1 23 | } ], 24 | 'space-infix-ops': [ 'error', { 'int32Hint': false } ], 25 | 'space-before-function-paren': [ 'error', { 26 | 'anonymous': 'always', 27 | 'named': 'always', 28 | 'asyncArrow': 'always' 29 | } ], 30 | 'semi': [ 'error', 'always' ], 31 | 'comma-dangle': 0, 32 | 'no-console': 0, 33 | 'no-debugger': 0, 34 | 'id-length': 0, 35 | 'eol-last': 0, 36 | 'object-curly-spacing': [ 'error', 'always' ], 37 | 'array-bracket-spacing': [ 'error', 'always' ], 38 | 'arrow-spacing': 'error', 39 | 'no-multiple-empty-lines': 'error', 40 | // 'no-unused-vars': 'error', 41 | 'spaced-comment': 'error', 42 | 'quotes': [ 'error', 'single', { 'allowTemplateLiterals': true } ], 43 | 'no-unreachable': 'error', 44 | 'keyword-spacing': 'error', 45 | 'space-before-blocks': 'error', 46 | 'semi-spacing': 'error', 47 | 'comma-spacing': 'error', 48 | 'key-spacing': 'error', 49 | 'prefer-const': [ 'error', { 50 | 'destructuring': 'any', 51 | 'ignoreReadBeforeAssign': false 52 | } ], 53 | 'space-infix-ops': 2, 54 | 'no-irregular-whitespace': 2, // 不规则的空白不允许 55 | 'no-trailing-spaces': 2, // 一行结束后面有空格就发出警告 56 | '@typescript-eslint/ban-ts-comment': 'off', 57 | '@typescript-eslint/no-unused-vars': 'error', 58 | } 59 | }; 60 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: alins 6 | ko_fi: theajack 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 13 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 14 | -------------------------------------------------------------------------------- /.github/release-drafter.yml: -------------------------------------------------------------------------------- 1 | name-template: 'v$RESOLVED_VERSION' 2 | tag-template: 'v$RESOLVED_VERSION' 3 | template: | 4 | # What's Changed 5 | 6 | ### [Version Log](https://github.com/alinsjs/alins/blob/master/scripts/helper/version.md) 7 | 8 | **Full Changelog**: https://github.com/$OWNER/$REPOSITORY/compare/$PREVIOUS_TAG...v$RESOLVED_VERSION 9 | 10 | categories: 11 | - title: 'Breaking' 12 | label: 'type: breaking' 13 | - title: 'New' 14 | label: 'type: feature' 15 | - title: 'Bug Fixes' 16 | label: 'type: bug' 17 | - title: 'Maintenance' 18 | label: 'type: maintenance' 19 | - title: 'Documentation' 20 | label: 'type: docs' 21 | - title: 'Other changes' 22 | - title: 'Dependency Updates' 23 | label: 'type: dependencies' 24 | collapse-after: 5 25 | 26 | version-resolver: 27 | major: 28 | labels: 29 | - 'type: breaking' 30 | minor: 31 | labels: 32 | - 'type: feature' 33 | patch: 34 | labels: 35 | - 'type: bug' 36 | - 'type: maintenance' 37 | - 'type: docs' 38 | - 'type: dependencies' 39 | - 'type: security' 40 | 41 | exclude-labels: 42 | - 'skip-changelog' 43 | -------------------------------------------------------------------------------- /.github/workflows/eb-docs.yml: -------------------------------------------------------------------------------- 1 | name: Docs 2 | on: 3 | push: 4 | tags: 5 | - d*.*.* 6 | 7 | jobs: 8 | build: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - name: Checkout 12 | uses: actions/checkout@v3 13 | with: 14 | fetch-depth: 0 15 | 16 | - name: Setup Node 17 | uses: actions/setup-node@v3 18 | with: 19 | node-version: '16' 20 | registry-url: https://registry.npmjs.org 21 | 22 | - name: Determine npm cache directory 23 | id: npm-cache 24 | run: | 25 | echo "::set-output name=dir::$(npm config get cache)" 26 | 27 | - name: Restore npm cache 28 | uses: actions/cache@v3 29 | with: 30 | path: ${{ steps.npm-cache.outputs.dir }} 31 | key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} 32 | restore-keys: | 33 | ${{ runner.os }}-node- 34 | 35 | - name: Npm Install 36 | run: npm install 37 | 38 | - name: Version 39 | id: version 40 | run: | 41 | tag=${GITHUB_REF/refs\/tags\//} 42 | version=${tag#d} 43 | echo "::set-output name=version::${version}" 44 | 45 | - name: Build docs # build npm 46 | run: npm run eb:docs -- ${{ steps.version.outputs.version }} 47 | 48 | - name: Pages # github pages 49 | uses: JamesIves/github-pages-deploy-action@v4.3.0 50 | with: 51 | branch: gh-pages 52 | folder: docs 53 | 54 | - name: Purge # purge cdn # 此处只需要purge docs即可 55 | run: npm run eb:purge -- ${{ steps.version.outputs.version }} -------------------------------------------------------------------------------- /.github/workflows/eb-release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | on: 3 | push: 4 | tags: 5 | - v*.*.* 6 | 7 | jobs: 8 | build: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - name: Checkout 12 | uses: actions/checkout@v3 13 | with: 14 | fetch-depth: 0 15 | 16 | - name: Setup Node 17 | uses: actions/setup-node@v3 18 | with: 19 | node-version: '16' 20 | registry-url: https://registry.npmjs.org 21 | 22 | - name: Determine npm cache directory 23 | id: npm-cache 24 | run: | 25 | echo "dir=$(npm config get cache)" >> $GITHUB_OUTPUT 26 | 27 | - name: Restore npm cache 28 | uses: actions/cache@v3 29 | with: 30 | path: ${{ steps.npm-cache.outputs.dir }} 31 | key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} 32 | restore-keys: | 33 | ${{ runner.os }}-node- 34 | 35 | - name: Npm Install pnpm 36 | run: npm install -g pnpm 37 | 38 | - name: pnpm Install --no-frozen-lockfile 39 | run: pnpm i --no-frozen-lockfile 40 | 41 | - name: Version 42 | id: version 43 | run: | 44 | tag=${GITHUB_REF/refs\/tags\//} 45 | version=${tag#v} 46 | echo "version=${version}" >> $GITHUB_OUTPUT 47 | 48 | - name: Build # build npm 49 | env: 50 | GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }} 51 | NODE_AUTH_TOKEN: ${{ secrets.NPMJS_TOKEN }} 52 | run: | 53 | git config --global user.email "1506282385@qq.com" 54 | git config --global user.name "theajack" 55 | git checkout master 56 | npx lerna bootstrap 57 | npx lerna version ${{ steps.version.outputs.version }} --no-git-tag-version --force-publish --yes 58 | npm run build 59 | git add . 60 | git commit -m "feat: Version ${{ steps.version.outputs.version }} Build" 61 | npx lerna publish from-package --yes 62 | npm run init:mono -- ${{ steps.version.outputs.version }} 63 | git add . 64 | git commit -m "feat: Version ${{ steps.version.outputs.version }} Publish" 65 | git push origin master 66 | 67 | # - name: Pages # github pages 68 | # uses: JamesIves/github-pages-deploy-action@v4.3.0 69 | # with: 70 | # branch: gh-pages 71 | # folder: docs 72 | 73 | - name: Release # release 74 | uses: release-drafter/release-drafter@v5 75 | with: 76 | version: ${{ steps.version.outputs.version }} 77 | publish: true 78 | env: 79 | GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }} 80 | 81 | # - name: Publish # npm publish 82 | # env: 83 | # NODE_AUTH_TOKEN: ${{ secrets.NPMJS_TOKEN }} 84 | # run: npm run eb:publish -- ${{ steps.version.outputs.version }} 85 | 86 | - name: Purge # purge cdn 87 | run: npm run eb:purge -- ${{ steps.version.outputs.version }} -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | cdn 4 | lerna-debug.log 5 | .pnpm-debug.log 6 | bundle.min.js 7 | bundle.min.js.map 8 | .DS_Store -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | strict-peer-dependencies=false 2 | registry=https://registry.npmjs.org/ 3 | auto-install-peers=true -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2022 - present 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /global.d.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-06-27 14:19:01 4 | * @Description: Coding something 5 | */ 6 | // eslint-disable-next-line no-var 7 | declare var __DEBUG__: boolean; 8 | -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "packages": [ 3 | "packages/*" 4 | ], 5 | "useNx": false, 6 | "version": "independent", 7 | "npmClient": "pnpm" 8 | } 9 | -------------------------------------------------------------------------------- /packages/client-core/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | node_modules 3 | pnpm-lock.yaml -------------------------------------------------------------------------------- /packages/client-core/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2022 - present 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /packages/client-core/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "alins", 3 | "version": "0.0.36", 4 | "description": "All-in-js Web UI Framework, No jsx/template/vdom/css/html", 5 | "main": "src/index.ts", 6 | "typings": "src/index.ts", 7 | "repository": "git@github.com:alinsjs/alins.git", 8 | "author": "tackchen ", 9 | "scripts": { 10 | "build": "node ../../scripts/build/build.js client-core" 11 | }, 12 | "keywords": [ 13 | "alins", 14 | "all-in-js", 15 | "alins-style", 16 | "css-in-js", 17 | "web-ui-framework" 18 | ], 19 | "license": "MIT", 20 | "dependencies": { 21 | "alins-reactive": "^0.0.36", 22 | "alins-utils": "^0.0.36" 23 | }, 24 | "publishConfig": { 25 | "registry": "https://registry.npmjs.org/" 26 | }, 27 | "module": "src/index.ts", 28 | "unpkg": "dist/alins.iife.min.js", 29 | "jsdelivr": "dist/alins.iife.min.js" 30 | } -------------------------------------------------------------------------------- /packages/client-core/src/branch/switch.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-07-03 09:09:46 4 | * @Description: Coding something 5 | */ 6 | 7 | import { IWatchRefTarget, watch } from 'alins-reactive'; 8 | import { ISimpleValue } from 'alins-utils'; 9 | import { BranchBlock } from './branch-block'; 10 | import { IGeneralElement, IReturnCall } from '../element/alins.d'; 11 | 12 | // export const _break = Symbol('b'); 13 | // export const _default = Symbol('d'); 14 | 15 | export type ISwitchTarget = IWatchRefTarget; 16 | 17 | export type ISwitchCase = [any, (()=>any)|null]; 18 | // value, call // ! , break, 19 | 20 | // ! break 在编译时处理了 运行时无需break参数 21 | 22 | export type ISwitchCaseList = ISwitchCase[]; 23 | 24 | 25 | // ! 编译时 return; return null; => return <> 26 | 27 | class SwitchBlock { 28 | private branch: BranchBlock; 29 | 30 | private endCall: IReturnCall; 31 | 32 | private target: ISwitchTarget; 33 | private caseList: ISwitchCaseList; 34 | 35 | constructor (target: ISwitchTarget, caseList: ISwitchCaseList) { 36 | this.branch = new BranchBlock(); 37 | this.target = target; 38 | this.caseList = caseList; 39 | } 40 | 41 | private run (value: any) { 42 | // console.log('switch debug:run', value); 43 | let matched: boolean = false; 44 | let el: any = null; 45 | const n = this.caseList.length; 46 | for (let i = 0; i < n; i++) { 47 | const item = this.caseList[i]; 48 | const [ caseValue, call ] = item; 49 | // 没有value表示为default 50 | if ( 51 | (Array.isArray(caseValue) && caseValue.includes(value)) || 52 | caseValue === value || 53 | caseValue === null 54 | ) { // 命中或走default 55 | // console.log('matched'); 56 | matched = true; 57 | const returned = this.branch.returned(call as any); 58 | el = this.branch.replace(i, !returned); 59 | if (!returned) { 60 | // @ts-ignore 61 | this.branch.replaceDom(this.endCall()); 62 | } 63 | break; 64 | } 65 | } 66 | if (!matched) { 67 | el = this.branch.replace(n); 68 | } 69 | return el; 70 | } 71 | 72 | end (call: IReturnCall = () => void 0): IGeneralElement|void { 73 | this.endCall = call; 74 | 75 | // ! 首次run初始化分支 76 | const initSwitchBranches = () => { 77 | for (const item of this.caseList) { 78 | const call = item[1]; 79 | if (call) { 80 | this.branch.add(call); 81 | } 82 | } 83 | this.branch.add(this.endCall); 84 | this.branch.quit(); 85 | }; 86 | 87 | // console.warn('switch end'); 88 | const init = watch(this.target, (value) => { 89 | // console.warn('switch debug: change', value); 90 | this.run(value); 91 | }); 92 | initSwitchBranches(); 93 | return this.run(init.v); 94 | } 95 | } 96 | 97 | export function _switch (target: ISwitchTarget, caseList: ISwitchCaseList) { 98 | return new SwitchBlock(target, caseList); 99 | } 100 | -------------------------------------------------------------------------------- /packages/client-core/src/context.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-07-02 18:41:35 4 | * @Description: Coding something 5 | */ 6 | 7 | import { _if } from './branch/if'; 8 | import { assignCompData, assignData, computed, mockRef, ref, watch } from 'alins-reactive'; 9 | import { _switch } from './branch/switch'; 10 | import './for'; 11 | import { JSX } from './element/element'; 12 | import { mockMap } from './for'; 13 | import { mount } from './element/renderer'; 14 | import { appended, created, mounted, removed } from './element/lifecycle'; 15 | 16 | export const _$ce = JSX.createElement; 17 | 18 | export const _$mt = mount; 19 | 20 | // ! 处理 async 代码没有返回值 21 | // markNotReturned 22 | export function _$mnr (fn: any) { 23 | fn.returned = false; 24 | return fn; 25 | } 26 | 27 | export const _$r = ref; 28 | export const _$c = computed; 29 | export const _$w = watch; 30 | 31 | export function _$cc (get: any, set: any) { // 简写,减少编译代码量 32 | return computed({ get, set }); 33 | } 34 | 35 | export const _$e = assignData; 36 | export const _$es = assignCompData; 37 | 38 | // markUpdateExpression: true 39 | export function _$mu (fn:any) { 40 | fn._update = true; 41 | return fn; 42 | } 43 | export const _$mf = mockRef; 44 | export const _$mm = mockMap; 45 | export const _$if = _if; 46 | export const _$sw = _switch; 47 | 48 | export function _$f (props: any, children: any[]) { 49 | return _$ce('', props, ...children); 50 | } 51 | 52 | export const _$cd = created; 53 | export const _$ad = appended; 54 | export const _$md = mounted; 55 | export const _$rd = removed; -------------------------------------------------------------------------------- /packages/client-core/src/element/attributes.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-07-21 22:37:05 4 | * @Description: Coding something 5 | */ 6 | import { isProxy } from 'alins-reactive'; 7 | import { reactiveBindingEnable } from './dom-util'; 8 | import type { IElement, IBaseAttributes } from './alins.d'; 9 | 10 | export function parseAttributes ( 11 | dom: IElement, 12 | value: IBaseAttributes | string | (()=>string) 13 | ): boolean { 14 | const REG = /(.*?)=(.*?)(&|$)/g; 15 | if (value === null || typeof value === 'undefined') return false; 16 | 17 | if (typeof value === 'function' || isProxy(value)) { 18 | // @ts-ignore 19 | reactiveBindingEnable(value, (v: any, ov: any, path, prop, remove) => { 20 | if (typeof v === 'string') { 21 | if (!prop || prop === 'v') { 22 | const r1 = v.matchAll(REG); 23 | v = {}; 24 | let item: any; 25 | while (!(item = r1.next()).done) v[item.value[1]] = item.value[2]; 26 | if (ov) { 27 | const r2 = ov.matchAll(REG); 28 | ov = {}; 29 | while (!(item = r2.next()).done) ov[item.value[1]] = item.value[2]; 30 | } else { 31 | ov = {}; 32 | } 33 | } else { 34 | !!remove ? 35 | dom.removeAttribute(prop) : 36 | dom.setAttribute(prop, v); 37 | return; 38 | } 39 | } 40 | for (const k in v) dom.setAttribute(k, v[k]); 41 | for (const k in ov) { 42 | if (typeof v[k] === 'undefined') 43 | dom.removeAttribute(k); 44 | } 45 | }); 46 | } else if (typeof value === 'object') { 47 | for (const k in value) { 48 | // !todo style value 编译 + func包裹 ()=>{} 49 | reactiveBindingEnable(value[k], (v) => { 50 | v === null ? 51 | dom.removeAttribute(v) : 52 | dom.setAttribute(k, v); 53 | }); 54 | } 55 | } else if (typeof value === 'string') { 56 | const r1 = value.matchAll(REG); 57 | let item: any; 58 | while (!(item = r1.next()).done) { 59 | dom.setAttribute(item.value[1], item.value[2]); 60 | } 61 | } else { 62 | return false; 63 | } 64 | return true; 65 | } -------------------------------------------------------------------------------- /packages/client-core/src/element/class.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-07-21 22:37:05 4 | * @Description: Coding something 5 | */ 6 | import { isProxy } from 'alins-reactive'; 7 | import { reactiveBindingEnable } from './dom-util'; 8 | import type { IElement } from './alins.d'; 9 | 10 | const SC = '_$single_class'; 11 | 12 | function setClass (dom: IElement, name: string, isRemove = false, single = false) { 13 | dom.classList[isRemove ? 'remove' : 'add'](name); 14 | 15 | if (single) { 16 | if (!dom[SC]) dom[SC] = new Set(); 17 | dom[SC][isRemove ? 'delete' : 'add'](name); 18 | } 19 | } 20 | 21 | function replaceClass (dom: IElement, v: string) { 22 | dom.className = Array.from(new Set(v.split(' '))).join(' '); 23 | const sc = dom[SC]; 24 | if (sc) sc.forEach((k: string) => {dom.classList.add(k);}); 25 | } 26 | 27 | export function parseClassName ( 28 | dom: IElement, 29 | value: {[prop in string]?: boolean} | string | (()=>string) 30 | ): boolean { 31 | 32 | if (value === null || typeof value === 'undefined') return false; 33 | if (typeof value === 'function' || isProxy(value)) { 34 | // @ts-ignore 35 | reactiveBindingEnable(value, (v: any, ov: any, path, prop, remove) => { 36 | if (typeof v === 'string') { 37 | replaceClass(dom, v); 38 | return; 39 | } else if (typeof v === 'boolean') { 40 | setClass(dom, prop, remove || v == false); 41 | return; 42 | } 43 | for (const k in v) { 44 | let value = v[k]; 45 | if (typeof value === 'function') { 46 | value = value(); 47 | } 48 | setClass(dom, k, value == false); 49 | } 50 | for (const k in ov) 51 | if (typeof v[k] === 'undefined') 52 | setClass(dom, k, true); 53 | }); 54 | // } else if(isProxy(value)){ 55 | // reactiveBindingEnable(value, (v,)) 56 | } else if (typeof value === 'object') { 57 | for (const k in value) { 58 | // !todo style value 编译 + func包裹 ()=>{} 59 | // @ts-ignore 60 | reactiveBindingEnable(value[k], (v) => { 61 | setClass(dom, k, !v); 62 | }); 63 | } 64 | } else if (typeof value === 'string') { 65 | replaceClass(dom, value); 66 | } 67 | return true; 68 | } 69 | 70 | export function parseClassSuffix (el: IElement, key: string, value: boolean|(()=>boolean)): boolean { 71 | if (!key.startsWith('class$')) return false; 72 | const name = key.substring('class$'.length); 73 | reactiveBindingEnable(value, (v) => { 74 | setClass(el, name, !v, true); 75 | }); 76 | return true; 77 | } -------------------------------------------------------------------------------- /packages/client-core/src/element/component.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-09-13 22:22:13 4 | * @Description: Coding something 5 | */ 6 | 7 | import { AlinsType, type } from 'alins-utils'; 8 | import { computed, isProxy } from 'alins-reactive'; 9 | import { getParent } from '../utils'; 10 | import { IAttributes, ITrueElement } from './alins.d'; 11 | import { appendChild, getFirstElement, Renderer } from './renderer'; 12 | import { CompLife } from './lifecycle'; 13 | 14 | export type IJSXComp = (( 15 | attributes: IAttributes|null, children: ITrueElement[] 16 | ) => ITrueElement|Promise) 17 | 18 | export function renderComponent ( 19 | comp: IJSXComp, 20 | attrs: IAttributes|null, 21 | children: any[], 22 | ) { 23 | const id = CompLife.enter(); 24 | const lifes: any = {}; 25 | let $mount: any = null; 26 | if (attrs) { 27 | for (const k in attrs) { 28 | const v = attrs[k]; 29 | switch (k) { 30 | case '$mount': $mount = v; delete attrs[k]; break; 31 | case '$created': 32 | case '$appended': 33 | case '$mounted': 34 | case '$removed': lifes[k] = v; delete attrs[k]; break; 35 | default: { 36 | if (!isProxy(v)) { 37 | attrs[k] = { v, [type]: AlinsType.Ref }; // ! 模拟ref 38 | } else { 39 | attrs[k] = computed(() => v.v, true); 40 | } 41 | }; break; 42 | } 43 | } 44 | } 45 | const dom = comp(attrs || {}, children); 46 | 47 | CompLife.fill(lifes, id, dom); 48 | 49 | const result = transformAsyncDom(dom, (realDom) => { 50 | const node = getFirstElement(realDom); 51 | for (const k in lifes) { 52 | const fn = lifes[k]; 53 | k === '$created' ? fn(node) : (node[`__${k}`] = fn); 54 | } 55 | }) as any; 56 | 57 | if ($mount) { 58 | if (typeof $mount === 'string') $mount = Renderer.querySelector($mount); 59 | appendChild($mount, result); 60 | } 61 | return result; 62 | } 63 | 64 | function transformAsyncDom ( 65 | dom: ITrueElement|Promise|null|void, 66 | onRealDom: (trueDom: any)=>void, 67 | ) { 68 | if (!dom) return dom; 69 | if (dom instanceof Promise) { 70 | // ! 此处是为了应对 元素没有立即append到dom上的情况 71 | const frag = Renderer.createFragment(); 72 | const node = Renderer.createEmptyMountNode(); 73 | frag.appendChild(node as any); 74 | dom.then((realDom: any) => { 75 | if (!Renderer.isElement(realDom)) return; 76 | const parent = getParent(node, frag); 77 | // ! 此处当async node被隐藏时 async执行完毕 此处会报错 78 | try { 79 | onRealDom?.(realDom); 80 | appendChild(parent, realDom, node); 81 | } catch (e) { 82 | console.log('node 已被隐藏'); 83 | } finally { 84 | node.remove(); 85 | } 86 | }); 87 | return frag; 88 | } 89 | onRealDom?.(dom); 90 | return dom; 91 | } 92 | -------------------------------------------------------------------------------- /packages/client-core/src/element/event.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-06-25 22:33:41 4 | * @Description: Coding something 5 | */ 6 | 7 | import { isProxy } from 'alins-reactive'; 8 | import { IElement, IFragment, IEventObject, IEventAttributes, IEventObjectDeco } from './alins'; 9 | 10 | export type IEventNames = keyof IEventAttributes; 11 | 12 | export function isEventAttr (dom: IElement|IFragment, name: string, e: IEventObject) { 13 | if (!name.startsWith('on')) return false; 14 | if (dom[name] !== null && typeof dom[name] !== 'function') return false; 15 | // @ts-ignore 16 | if ( 17 | typeof e !== 'function' && 18 | typeof e?.listener !== 'function' && 19 | // @ts-ignore 20 | typeof e?.__deco !== 'string' && 21 | typeof e?.v !== 'function' 22 | ) return false; 23 | return true; 24 | } 25 | 26 | export function addEvent (dom: IElement, name: string, event: IEventObjectDeco) { 27 | name = name.substring(2); 28 | if (typeof event === 'function') { 29 | dom.addEventListener(name, event); 30 | } else if (isProxy(event)) { 31 | // @ts-ignore 32 | dom.addEventListener(name, event.v); 33 | } else { 34 | // @ts-ignore 35 | if (event.__deco) { 36 | // @ts-ignore 37 | const deco = event.__deco.split('-'); 38 | event = { 39 | // @ts-ignore 40 | listener: event.v, 41 | } as IEventObjectDeco; 42 | for (const name of deco) { 43 | event[name] = true; 44 | } 45 | } 46 | const handle = (e: Event) => { 47 | // @ts-ignore 48 | if (event.self && e.target !== dom) return; 49 | if (event.stop) e.stopPropagation(); 50 | if (event.prevent) e.preventDefault(); 51 | if (event.once) dom.removeEventListener(name, handle, event.capture); 52 | event.listener(e); 53 | }; 54 | dom.addEventListener(name, handle, event.capture); 55 | } 56 | } -------------------------------------------------------------------------------- /packages/client-core/src/element/model.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-07-21 22:37:05 4 | * @Description: Coding something 5 | */ 6 | import type { IRefData, ISimpleValue } from 'alins-utils'; 7 | import { isProxy, watch } from 'alins-reactive'; 8 | import type { IElement } from './alins.d'; 9 | 10 | const ModelTag = { 11 | INPUT: 1, SELECT: 1, TEXTAREA: 1, 12 | }; 13 | 14 | export function parseModel ( 15 | dom: IElement, 16 | value: ISimpleValue | (()=>ISimpleValue) | IRefData, 17 | k: string, 18 | ): boolean { 19 | if (k !== 'value' && k !== 'checked') return false; 20 | 21 | // @ts-ignore 22 | if (!isProxy(value) && !value.__deco) return false; // 不是proxy不支持双向绑定 23 | const tag = dom.tagName; 24 | if (!ModelTag[tag]) return false; 25 | 26 | // @ts-ignore 27 | const type = value.__deco || typeof value.v; 28 | let parseType = ({ 29 | 'boolean': v => v === 'true', 30 | 'number': v => parseFloat(v), 31 | 'string': v => v, 32 | })[type]; 33 | 34 | if (!parseType) parseType = v => v; 35 | // @ts-ignore 36 | const bindValue = value.__deco ? value.v : value; 37 | 38 | const eventName = tag === 'SELECT' ? 'change' : 'input'; 39 | dom.addEventListener(eventName, () => { 40 | let newValue = dom[k]; 41 | if (type !== typeof newValue) { 42 | newValue = parseType(newValue); 43 | } 44 | bindValue.v = Number.isNaN(newValue) ? '' : newValue; 45 | }); 46 | watch(bindValue, (v: any) => { 47 | dom[k] = v; 48 | }, false); 49 | dom[k] = bindValue.v; 50 | return true; 51 | } -------------------------------------------------------------------------------- /packages/client-core/src/element/style.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-07-21 22:37:05 4 | * @Description: Coding something 5 | */ 6 | import { isProxy } from 'alins-reactive'; 7 | import { reactiveBindingEnable } from './dom-util'; 8 | import type { IElement, IStyle } from './alins.d'; 9 | 10 | export const OnlyNumberMap = { 'zIndex': 1, 'opacity': 1, 'flex': 1, 'flexGrow': 1, 'flexShrink': 1 }; 11 | 12 | const SS = '_$single_style'; 13 | 14 | function setStyle (dom: IElement, prop: string, v: any, remove?: boolean, single = false) { 15 | if (typeof v === 'number' && !OnlyNumberMap[prop]) { 16 | v = `${v}px`; 17 | } 18 | v = !!remove ? '' : v; 19 | dom.style[prop] = v; 20 | 21 | if (single) { 22 | if (!dom[SS]) dom[SS] = {}; 23 | dom[SS][prop] = v; 24 | } 25 | } 26 | 27 | export function parseStyle ( 28 | dom: IElement, 29 | value: IStyle | string | (()=>string) 30 | ): boolean { 31 | if (value === null || typeof value === 'undefined') return false; 32 | if (typeof value === 'function' || isProxy(value)) { 33 | const isFunc = typeof value === 'function'; 34 | // @ts-ignore 35 | reactiveBindingEnable(value, (v: any, ov: any, path, prop, remove) => { 36 | if (typeof v === 'string') { 37 | if (isFunc) { 38 | // if (!prop || prop === 'v') { 39 | dom.setAttribute('style', v); 40 | const ss = dom[SS]; 41 | if (ss) { 42 | for (const k in ss) dom.style[k] = ss[k]; 43 | } 44 | } else { 45 | setStyle(dom, prop, v, remove); 46 | } 47 | return; 48 | } 49 | for (const k in v) { 50 | let value = v[k]; 51 | if (typeof value === 'function') { 52 | value = value(); 53 | } 54 | setStyle(dom, k, value); 55 | } 56 | for (const k in ov) 57 | if (typeof v[k] === 'undefined') 58 | setStyle(dom, k, ''); 59 | }); 60 | // } else if(isProxy(value)){ 61 | // reactiveBindingEnable(value, (v,)) 62 | } else if (typeof value === 'object') { 63 | for (const k in value) { 64 | // !todo style value 编译 + func包裹 ()=>{} 65 | // @ts-ignore 66 | reactiveBindingEnable(value[k], (v) => { 67 | setStyle(dom, k, v, v === null); 68 | }); 69 | } 70 | } else { 71 | return false; 72 | } 73 | return true; 74 | } 75 | 76 | export function parseStyleSuffix (el: IElement, key: string, value: any|(()=>any)): boolean { 77 | if (!key.startsWith('style$')) return false; 78 | const name = key.substring('style$'.length); 79 | reactiveBindingEnable(value, (v) => { 80 | setStyle(el, name, v, v === null, true); 81 | }); 82 | return true; 83 | } -------------------------------------------------------------------------------- /packages/client-core/src/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-08-02 19:35:29 4 | * @Description: Coding something 5 | */ 6 | 7 | export * from './context'; 8 | 9 | export * from './element/alins.d'; 10 | 11 | export { _if } from './branch/if'; 12 | export { _switch } from './branch/switch'; 13 | export { map } from './for'; 14 | 15 | export * from './element/renderer'; 16 | export * from './element/custom-renderer'; 17 | 18 | export * from 'alins-reactive'; 19 | 20 | export * from './element/jsx.d'; 21 | 22 | export { appended, created, mounted, removed } from './element/lifecycle'; 23 | 24 | export const version = __VERSION__; 25 | 26 | export { reactiveBindingEnable } from './element/dom-util'; 27 | export * from 'alins-utils'; 28 | -------------------------------------------------------------------------------- /packages/client-core/src/utils.ts: -------------------------------------------------------------------------------- 1 | import { Renderer } from './element/renderer'; 2 | 3 | /* 4 | * @Author: chenzhongsheng 5 | * @Date: 2023-07-04 09:52:35 6 | * @Description: Coding something 7 | */ 8 | export function createEmptyJson () { 9 | const json = {}; 10 | // @ts-ignore 11 | json.__proto__ = null; 12 | return json; 13 | } 14 | 15 | export function getParent (node: any, def: any = null) { 16 | return node.parentElement || node.parentNode || def; 17 | } 18 | 19 | export function insertBefore (array: any[], node: any, child: any) { 20 | const index = array.indexOf(child); 21 | if (index === -1) return; 22 | 23 | if (Renderer.isFragment(node)) { 24 | node = Array.from(node.childNodes); 25 | } else { 26 | node = [ node ]; 27 | } 28 | // console.log('insertBefore', node, index); 29 | if (index === 0) { 30 | // @ts-ignore 31 | array.unshift(...node); 32 | } else { 33 | array.splice(index, 0, ...node); 34 | } 35 | } -------------------------------------------------------------------------------- /packages/client-reactive/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | node_modules 3 | pnpm-lock.yaml -------------------------------------------------------------------------------- /packages/client-reactive/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2022 - present 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /packages/client-reactive/README.md: -------------------------------------------------------------------------------- 1 | 2 |

3 | 4 |

5 | 6 |

7 | 8 | stars 9 | 10 | 11 | forks 12 | 13 | 14 | version 15 | 16 | 17 | downloads 18 | 19 | 20 | jsdelivr 21 | 22 | visitors 23 |

24 | 25 |

26 | 27 | author 28 | 29 | 30 | license 31 | 32 | Size 33 | TopLang 34 | issue 35 | Dependent 36 |

37 | 38 | ## 🚀 [Alins](https://github.com/alinsjs/alins): The most pure and elegant WebUI framework 39 | 40 | **[中文](https://github.com/alinsjs/alins/blob/master/README.cn.md) | [Documentation](https://alinsjs.github.io/docs) | [Playground](https://alinsjs.github.io/playground/) | [Update Log](https://github.com/alinsjs/alins/blob/master/scripts/helper/version.md) | [Feedback Errors/Defects](https://github.com/alinsjs/alins/issues/new) | [Gitee](https://gitee.com/alinsjs/alins) | [Message Board](https://theajack.github.io/message-board/?app=alins)** 41 | 42 | ## alins-reactive 43 | 44 | -------------------------------------------------------------------------------- /packages/client-reactive/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "alins-reactive", 3 | "version": "0.0.36", 4 | "description": "All-in-js Web UI Framework, No jsx/template/vdom/css/html", 5 | "main": "src/index.ts", 6 | "typings": "src/index.ts", 7 | "repository": "git@github.com:alinsjs/alins.git", 8 | "author": "tackchen ", 9 | "scripts": { 10 | "build": "node ../../scripts/build/build.js client-reactive" 11 | }, 12 | "keywords": [ 13 | "alins", 14 | "all-in-js", 15 | "alins-style", 16 | "css-in-js", 17 | "web-ui-framework" 18 | ], 19 | "license": "MIT", 20 | "dependencies": { 21 | "alins-utils": "^0.0.36" 22 | }, 23 | "publishConfig": { 24 | "registry": "https://registry.npmjs.org/" 25 | }, 26 | "unpkg": "dist/alins-reactive.iife.min.js", 27 | "jsdelivr": "dist/alins-reactive.iife.min.js", 28 | "module": "src/index.ts" 29 | } -------------------------------------------------------------------------------- /packages/client-reactive/src/cleaner.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-08-13 12:17:41 4 | * @Description: Coding something 5 | */ 6 | 7 | export interface ICleaner { 8 | clean(): void; 9 | collect(clean: any): void; 10 | } 11 | 12 | let curCleaner: ICleaner|null = null; 13 | 14 | export function setCurCleaner (cleaner: ICleaner|null) { 15 | curCleaner = cleaner; 16 | } 17 | 18 | export function getCurCleaner () { 19 | return curCleaner; 20 | } 21 | 22 | export function useCurCleaner (cleaner: ICleaner|null, callback: ()=>T) { 23 | setCurCleaner(cleaner); 24 | // console.warn('useCurCleaner'); 25 | const result = callback(); 26 | setCurCleaner(null); 27 | return result; 28 | } 29 | 30 | // 收集dom元素依赖的watch,在元素remove时主动释放掉所有watch 31 | export function createCleaner () { 32 | 33 | let cleanMap: any[] = []; 34 | 35 | const cleaner: ICleaner = { 36 | clean () { 37 | cleanMap.forEach(clean => { 38 | clean(); 39 | }); 40 | // @ts-ignore 41 | cleanMap = null; 42 | }, 43 | collect (clean: any) { 44 | if (!cleanMap) return; 45 | cleanMap.push(clean); 46 | } 47 | }; 48 | 49 | curCleaner = cleaner; 50 | 51 | return curCleaner; 52 | } -------------------------------------------------------------------------------- /packages/client-reactive/src/computed.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-06-26 11:18:42 4 | * @Description: Coding something 5 | */ 6 | 7 | import { util, IRefData, IOnChange } from 'alins-utils'; 8 | import { observe, createProxy, wrapReactive } from './proxy'; 9 | import { isDepReactive } from './proxy'; 10 | 11 | export interface IComputedObject { 12 | get(): T; 13 | set?: IOnChange; 14 | } 15 | 16 | // ! computed 都为ref,且都是shallow 17 | export function computed (target:(()=>T)|IComputedObject, isProp = false): IRefData|{v: T} { 18 | const isFunc = typeof target === 'function'; 19 | // @ts-ignore 20 | const get = isFunc ? target : target.get; 21 | const set = isFunc ? null : (target as IComputedObject).set; 22 | 23 | let proxy: IRefData; 24 | 25 | let computing = false; 26 | let cache: any = null; 27 | const v = observe(get, () => { 28 | // console.log('warn observe', JSON.stringify(proxy)); 29 | // ! 每次都需要重新get一下 因为可能代码逻辑分支有变化导致出现了没有收集到的依赖 30 | if (!computing) { 31 | computing = true; 32 | cache = proxy?.[util].forceWrite(get(), 'v'); 33 | computing = false; 34 | } else { 35 | proxy?.[util].forceWrite(cache, 'v'); 36 | } 37 | /** 38 | ! BAD CASE 39 | let age = 0; 40 | const age1 = age++; 41 | ; 42 | */ 43 | }); 44 | cache = v; 45 | 46 | if (isDepReactive()) { 47 | // todo check return cache 48 | proxy = createProxy(wrapReactive(v, true), { set, get, isProp }); 49 | return proxy; 50 | } 51 | // ! 此处是为了兼容编译时将未知类型的import常量进行表达式计算时进行的统一computed处理的开销 52 | // 也可以优化 computed静态类型的开销 如 computed(()=>1+1) 53 | return { v }; 54 | } 55 | 56 | -------------------------------------------------------------------------------- /packages/client-reactive/src/extends.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-08-18 23:47:24 4 | * @Description: Coding something 5 | */ 6 | import {computed} from './computed'; 7 | import {isProxy} from './proxy'; 8 | 9 | export function assignData (...data: any[]) { 10 | return assignBase(data, false); 11 | } 12 | 13 | export function assignCompData (...data: any[]) { 14 | return assignBase(data, true); 15 | } 16 | 17 | function assignBase (data: any[], isComp: boolean) { 18 | data.forEach((item, index) => { 19 | if (isProxy(item)) { 20 | const newData = {}; 21 | for (const k in item) { 22 | newData[k] = () => item[k]; 23 | if (isComp) { 24 | newData[k] = computed(newData[k]); 25 | } 26 | } 27 | data[index] = newData; 28 | } 29 | }); 30 | // @ts-ignore 31 | return Object.assign.apply(null, data); 32 | } -------------------------------------------------------------------------------- /packages/client-reactive/src/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-06-26 11:00:41 4 | * @Description: Coding something 5 | */ 6 | export * from './proxy'; 7 | export * from './reactive'; 8 | export * from './computed'; 9 | export * from './watch'; 10 | export * from 'alins-utils'; 11 | 12 | export * from './array-proxy'; 13 | 14 | export * from './cleaner'; 15 | export * from './extends'; 16 | 17 | export * from './store'; -------------------------------------------------------------------------------- /packages/client-reactive/src/reactive.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-06-26 11:00:45 4 | * @Description: Coding something 5 | */ 6 | 7 | import { 8 | IJson, 9 | IProxyData, 10 | } from 'alins-utils'; 11 | import { createProxy, isProxy, wrapReactive } from './proxy'; 12 | 13 | export function reactive (data: T, shallow = false): IProxyData { 14 | if (isProxy(data.v)) return data as any; 15 | // @ts-ignore 16 | return createProxy(wrapReactive(data) as T, { shallow }); 17 | } 18 | 19 | export function ref (v: T, shallow?: boolean) { 20 | if (typeof shallow !== 'boolean') { 21 | // @ts-ignore 22 | shallow = typeof v?.v === 'object' && isProxy(v.v); 23 | } 24 | return reactive<{v: T}>({ v }, shallow); 25 | } 26 | -------------------------------------------------------------------------------- /packages/client-reactive/src/watch.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-06-26 15:31:14 4 | * @Description: Coding something 5 | */ 6 | import { IProxyListener, IProxyData, util, IRefData, trig, empty } from 'alins-utils'; 7 | import { isProxy, observe } from './proxy'; 8 | // import {computed} from './computed'; 9 | import { IOprationAction } from './array-proxy'; 10 | 11 | export type IWatchRefTarget = (()=>T)|IRefData|{v:T}; 12 | export type IWatchTarget = IWatchRefTarget|(IProxyData); 13 | 14 | export function watchRef ( 15 | target: IWatchRefTarget, 16 | cb: IProxyListener, 17 | ): IRefData|{v:T} { 18 | return watch(target, cb, false) as any; 19 | } 20 | 21 | function isValueEqual (v1: any, v2: any, deep: boolean = true, first = true): boolean { 22 | if (v1 && v2 && typeof v1 === 'object' && typeof v2 === 'object' && (first || deep)) { 23 | if (Array.isArray(v1)) { 24 | if (v1.length !== v2.length) return false; 25 | } else { 26 | if (Object.keys(v1).length !== Object.keys(v2).length) return false; 27 | } 28 | for (const k in v1) { 29 | if (!isValueEqual(v1[k], v2[k], deep, false)) return false; 30 | } 31 | return true; 32 | } else { 33 | return v1 === v2; 34 | } 35 | } 36 | 37 | export function watch ( 38 | target: IWatchTarget, 39 | cb: IProxyListener, 40 | deep = true, 41 | ): IProxyData|IRefData|{v:T} { 42 | // console.warn('watch', target); 43 | if (typeof target === 'function') { 44 | let before: any = empty; 45 | before = observe(target, (v, nv, path, p, remove) => { 46 | // console.log('observe', v, nv, path); 47 | // ! 对于 UpdateExpression 直接用v作为新值 如果通过target会循环调用 (Maximum call stack size excee) 48 | // @ts-ignore 49 | // const after = target._update ? v : observe(target, fn); 50 | const after = target._update ? v : target(); 51 | if (!isValueEqual(before, after)) { 52 | // console.log(after, before, path, p, remove); 53 | cb(after, before, path, p, remove); 54 | before = after; 55 | } else { 56 | return after; 57 | } 58 | }); 59 | return { v: before }; 60 | } else if (!isProxy(target)) { 61 | // ! 兼容computed(()=>1+1)情况 62 | return target; 63 | } 64 | // @ts-ignore 65 | if (target[util]) { // ! 没有 util 表示不是proxy 66 | // @ts-ignore 67 | target[util].subscribe(cb, deep); 68 | } 69 | return target; 70 | }; 71 | 72 | export function watchArray ( 73 | target: IProxyData, 74 | listener: ({ index, count, data, type }: IOprationAction)=>void 75 | ) { 76 | // @ts-ignore 77 | if (!target[trig]) { 78 | // @ts-ignore 79 | target[trig] = [ listener ]; 80 | } else { 81 | // @ts-ignore 82 | target[trig].push(listener); 83 | } 84 | } 85 | 86 | // window.watchArray = watchArray; -------------------------------------------------------------------------------- /packages/client-standalone/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | node_modules 3 | pnpm-lock.yaml -------------------------------------------------------------------------------- /packages/client-standalone/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2022 - present 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /packages/client-standalone/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "alins-standalone", 3 | "version": "0.0.36", 4 | "description": "All-in-js Web UI Framework, No jsx/template/vdom/css/html", 5 | "main": "src/index.ts", 6 | "typings": "src/index.ts", 7 | "repository": "git@github.com:alinsjs/alins.git", 8 | "author": "tackchen ", 9 | "scripts": { 10 | "build": "node ../../scripts/build/build.js client-standalone" 11 | }, 12 | "keywords": [ 13 | "alins", 14 | "all-in-js", 15 | "alins-style", 16 | "css-in-js", 17 | "web-ui-framework" 18 | ], 19 | "license": "MIT", 20 | "publishConfig": { 21 | "registry": "https://registry.npmjs.org/" 22 | }, 23 | "unpkg": "dist/alins-standalone.iife.min.js", 24 | "jsdelivr": "dist/alins-standalone.iife.min.js", 25 | "dependencies": { 26 | "alins": "^0.0.36" 27 | }, 28 | "module": "src/index.ts" 29 | } -------------------------------------------------------------------------------- /packages/client-utils/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | node_modules 3 | pnpm-lock.yaml -------------------------------------------------------------------------------- /packages/client-utils/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2022 - present 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /packages/client-utils/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "alins-utils", 3 | "version": "0.0.36", 4 | "description": "All-in-js Web UI Framework, No jsx/template/vdom/css/html", 5 | "main": "src/index.ts", 6 | "typings": "src/index.ts", 7 | "repository": "git@github.com:alinsjs/alins.git", 8 | "author": "tackchen ", 9 | "scripts": { 10 | "build": "node ../../scripts/build/build.js client-utils" 11 | }, 12 | "keywords": [ 13 | "alins", 14 | "all-in-js", 15 | "alins-style", 16 | "css-in-js", 17 | "web-ui-framework" 18 | ], 19 | "license": "MIT", 20 | "publishConfig": { 21 | "registry": "https://registry.npmjs.org/" 22 | }, 23 | "unpkg": "dist/alins-utils.iife.min.js", 24 | "jsdelivr": "dist/alins-utils.iife.min.js", 25 | "module": "src/index.ts" 26 | } -------------------------------------------------------------------------------- /packages/client-utils/src/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: tackchen 3 | * @Date: 2022-10-23 18:24:06 4 | * @Description: Coding something 5 | */ 6 | export * from './types/symbol'; 7 | export { version } from '../package.json'; 8 | 9 | export * from './types/common.d'; 10 | export * from './types/react.d'; 11 | // export * from './types/style.d'; 12 | export * from './types/enum'; -------------------------------------------------------------------------------- /packages/client-utils/src/types/common.d.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: tackchen 3 | * @Date: 2022-10-11 16:41:40 4 | * @Description: Coding something 5 | */ 6 | export interface IJson { 7 | [prop: string | symbol]: T; 8 | } 9 | -------------------------------------------------------------------------------- /packages/client-utils/src/types/enum.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-06-27 10:41:19 4 | * @Description: Coding something 5 | */ 6 | export enum AlinsType { 7 | Proxy = 1, 8 | Ref, 9 | BindResult, 10 | } -------------------------------------------------------------------------------- /packages/client-utils/src/types/react.d.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: tackchen 3 | * @Date: 2022-10-23 19:26:19 4 | * @Description: Coding something 5 | */ 6 | 7 | import { IJson } from './common'; 8 | import { AlinsType } from './enum'; 9 | import { type, util } from './symbol'; 10 | 11 | export type ISimpleValue = string|number|boolean; 12 | 13 | export type IOnChange = (nv: T, ov: T, path: string, prop: string, remove?: boolean) => void; 14 | 15 | // Reactive 16 | export interface IProxyUtils { 17 | path: string[]; 18 | lns: IProxyListenerMap; 19 | commonLns?: Set; 20 | triggerChange: (property: string, nv: any, old?: any, remove?: boolean, isNew?: boolean) => void; 21 | forceWrite: (v: any, k?: string) => void; 22 | subscribe: (ln: IProxyListener, deep?: boolean) => void; 23 | isArray: boolean; 24 | shallow: boolean; 25 | forceUpdate: ()=>void; 26 | // clearCache: ()=>void; 27 | proxy: IProxyData; 28 | scopeItems?: any[]; 29 | replaceLns?: boolean; 30 | extraLns?: Set; 31 | data: any; 32 | } 33 | 34 | export interface IProxyBase { 35 | // @ts-ignore 36 | [util]: IProxyUtils; 37 | // @ts-ignore 38 | [type]: T; 39 | } 40 | 41 | export interface IRefData extends IProxyBase { 42 | v: T; 43 | } 44 | 45 | 46 | export type IProxyData< 47 | T, 48 | K = T extends object ? (T & IProxyBase) : IRefData 49 | > = K; 50 | 51 | export type IProxyListener = IOnChange; 52 | export type IProxyListenerMap = IJson>; 53 | -------------------------------------------------------------------------------- /packages/client-utils/src/types/symbol.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2022-10-23 21:35:28 4 | * @Description: Coding something 5 | */ 6 | export const type = Symbol('t'); 7 | export const util = Symbol('u'); 8 | export const child = Symbol('c'); 9 | export const empty = Symbol('e'); 10 | export const trig = Symbol('t'); 11 | export const pureproxy = Symbol('pp'); 12 | // export const type = '__$a_type'; 13 | // export const util = '__$a_util'; 14 | // export const child = '__$a_child'; 15 | // export const empty = '__$a_empty'; 16 | // export const trig = '__$a_trig'; 17 | // export const pureproxy = '__$a_pp'; 18 | 19 | // window.util = util; -------------------------------------------------------------------------------- /packages/client-utils/src/utils.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: tackchen 3 | * @Date: 2022-10-11 16:54:25 4 | * @Description: Coding something 5 | */ -------------------------------------------------------------------------------- /packages/compiler-core/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | node_modules 3 | pnpm-lock.yaml -------------------------------------------------------------------------------- /packages/compiler-core/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2022 - present 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /packages/compiler-core/README.md: -------------------------------------------------------------------------------- 1 | 2 |

3 | 4 |

5 | 6 |

7 | 8 | stars 9 | 10 | 11 | forks 12 | 13 | 14 | version 15 | 16 | 17 | downloads 18 | 19 | 20 | jsdelivr 21 | 22 | visitors 23 |

24 | 25 |

26 | 27 | author 28 | 29 | 30 | license 31 | 32 | Size 33 | TopLang 34 | issue 35 | Dependent 36 |

37 | 38 | ## 🚀 [Alins](https://github.com/alinsjs/alins): The most pure and elegant WebUI framework 39 | 40 | **[中文](https://github.com/alinsjs/alins/blob/master/README.cn.md) | [Documentation](https://alinsjs.github.io/docs) | [Playground](https://alinsjs.github.io/playground/) | [Update Log](https://github.com/alinsjs/alins/blob/master/scripts/helper/version.md) | [Feedback Errors/Defects](https://github.com/alinsjs/alins/issues/new) | [Gitee](https://gitee.com/alinsjs/alins) | [Message Board](https://theajack.github.io/message-board/?app=alins)** 41 | 42 | ## [alins-compiler-core](https://www.npmjs.com/package/alins-compiler-core) 43 | 44 | Compiler core module, basically developers do not need to use this module. 45 | 46 | This module can generate a universal babel plug-in that supports use in web and nodejs environments. The alins-compiler-node above and the web compiler in subsequent chapters all rely on this module. 47 | 48 | ```js 49 | import {createBabelPluginAlins} from 'alins-compiler-core'; 50 | const babelPlugin = createBabelPluginAlins(); 51 | ``` -------------------------------------------------------------------------------- /packages/compiler-core/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "alins-compiler-core", 3 | "version": "0.0.36", 4 | "description": "All-in-js Web UI Framework, No jsx/template/vdom/css/html", 5 | "main": "src/index.ts", 6 | "typings": "src/index.ts", 7 | "repository": "git@github.com:alinsjs/alins.git", 8 | "author": "tackchen ", 9 | "scripts": { 10 | "build": "node ../../scripts/build/build.js compiler-core" 11 | }, 12 | "keywords": [ 13 | "alins", 14 | "all-in-js", 15 | "alins-style", 16 | "css-in-js", 17 | "web-ui-framework" 18 | ], 19 | "license": "MIT", 20 | "publishConfig": { 21 | "registry": "https://registry.npmjs.org/" 22 | }, 23 | "dependencies": { 24 | "@babel/types": "^7.22.5", 25 | "@types/babel__traverse": "^7.20.1" 26 | }, 27 | "module": "src/index.ts", 28 | "type": "commonjs" 29 | } -------------------------------------------------------------------------------- /packages/compiler-core/pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: '6.0' 2 | 3 | settings: 4 | autoInstallPeers: true 5 | excludeLinksFromLockfile: false 6 | 7 | dependencies: 8 | '@babel/types': 9 | specifier: ^7.22.5 10 | version: 7.22.15 11 | '@types/babel__traverse': 12 | specifier: ^7.20.1 13 | version: 7.20.1 14 | 15 | packages: 16 | 17 | /@babel/helper-string-parser@7.22.5: 18 | resolution: {integrity: sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==} 19 | engines: {node: '>=6.9.0'} 20 | dev: false 21 | 22 | /@babel/helper-validator-identifier@7.22.15: 23 | resolution: {integrity: sha512-4E/F9IIEi8WR94324mbDUMo074YTheJmd7eZF5vITTeYchqAi6sYXRLHUVsmkdmY4QjfKTcB2jB7dVP3NaBElQ==} 24 | engines: {node: '>=6.9.0'} 25 | dev: false 26 | 27 | /@babel/types@7.22.15: 28 | resolution: {integrity: sha512-X+NLXr0N8XXmN5ZsaQdm9U2SSC3UbIYq/doL++sueHOTisgZHoKaQtZxGuV2cUPQHMfjKEfg/g6oy7Hm6SKFtA==} 29 | engines: {node: '>=6.9.0'} 30 | dependencies: 31 | '@babel/helper-string-parser': 7.22.5 32 | '@babel/helper-validator-identifier': 7.22.15 33 | to-fast-properties: 2.0.0 34 | dev: false 35 | 36 | /@types/babel__traverse@7.20.1: 37 | resolution: {integrity: sha512-MitHFXnhtgwsGZWtT68URpOvLN4EREih1u3QtQiN4VdAxWKRVvGCSvw/Qth0M0Qq3pJpnGOu5JaM/ydK7OGbqg==} 38 | dependencies: 39 | '@babel/types': 7.22.15 40 | dev: false 41 | 42 | /to-fast-properties@2.0.0: 43 | resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} 44 | engines: {node: '>=4'} 45 | dev: false 46 | -------------------------------------------------------------------------------- /packages/compiler-core/src/controller/control-scope.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-07-17 07:55:32 4 | * @Description: Coding something 5 | */ 6 | import type { Statement } from '@babel/types'; 7 | import type { NodePath } from '@babel/traverse'; 8 | import type { Scope } from '../scope'; 9 | 10 | export abstract class ControlScope { 11 | replaceEnd: (node: Statement[])=>void; 12 | parent: ControlScope|null = null; ; 13 | path: NodePath; 14 | newNode: any; 15 | top = false; 16 | 17 | isReturnJsx = false; 18 | markScopeReturnJsx () { 19 | if (this.isReturnJsx) return; 20 | this.isReturnJsx = true; 21 | this.parent?.markScopeReturnJsx(); 22 | } 23 | 24 | // todo 根据 if test 中是否是响应数据来决定是否需要 replace if 暂时先全部replace处理 25 | // isReactive = true; 26 | 27 | // // ! 标识当前if块是否一定会返回值 28 | // returned = true; 29 | 30 | parentScope: Scope; 31 | 32 | recordAwait = true; 33 | 34 | constructor (path: NodePath, scope: Scope) { 35 | this.path = path; 36 | this.parentScope = scope; 37 | this.top = scope.isTopScope; 38 | // @ts-ignore 39 | if (path.node._isComReact) { 40 | this.markScopeReturnJsx(); 41 | } 42 | this._init(); 43 | } 44 | abstract _init (): void; 45 | 46 | exit () { 47 | // 记录end是否是async 48 | // console.log('recordAwait', this.recordAwait); 49 | if (this.recordAwait) { 50 | this.parentScope.startRecordAwait(); 51 | } 52 | 53 | // ! 此处可以配合reactive决定是否需要立即replace 54 | /* 55 | 如果当前if中没有reactive条件 可以全局维护一个replace队列 56 | 在 Program.exit 统一replace 57 | if(this.reactive){ 58 | this.path.replaceWith(this.newNode); 59 | }else{ 60 | globalQueue.push(()=>{ 61 | if(this.reactive){ // ! 遍历过程中记录是否有reactive数据 62 | this.path.replaceWith(this.newNode); 63 | } 64 | }) 65 | } 66 | */ 67 | if (this.newNode && this.isReturnJsx) { 68 | this.path.replaceWith(this.newNode); 69 | // @ts-ignore 70 | this.newNode = null; 71 | } 72 | 73 | return this.parent; 74 | } 75 | } -------------------------------------------------------------------------------- /packages/compiler-core/src/controller/func-reactive.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-08-16 00:23:16 4 | * @Description: Coding something 5 | * 6 | * 7 | let a = 0; 8 | a ++; 9 | const fn = () => a + 1; 10 | const dom =
; 11 | * 12 | */ 13 | import type {Node, NodePath} from '@babel/traverse'; 14 | import type {Scope, IScopeVariable} from '../scope'; 15 | 16 | export class FuncReactiveScope { 17 | 18 | returnJsx = false; 19 | scope: Scope; 20 | 21 | isReactive = false; 22 | 23 | path: NodePath; 24 | 25 | variable: IScopeVariable; 26 | 27 | constructor (scope: Scope, path: NodePath) { 28 | this.scope = scope; 29 | // @ts-ignore 30 | this.variable = path.node._variable; 31 | try { 32 | this.variable._func_scope = this; 33 | } catch (e) { 34 | // debugger; 35 | console.warn('FuncReactiveScope', e); 36 | } 37 | } 38 | markReturnJsx () { 39 | this.returnJsx = true; 40 | } 41 | 42 | collectIdentifier (variable: IScopeVariable) { 43 | if (this.isReactive) return; 44 | if (variable.isReactive) { 45 | this.isReactive = true; 46 | this.variable.isReactive = true; 47 | } else { 48 | if (!variable.dependActions) variable.dependActions = []; 49 | variable.dependActions.push(() => { 50 | this.isReactive = true; 51 | this.variable.isReactive = true; 52 | this.scope._updateDependIdentifier(this.variable, false); 53 | }); 54 | } 55 | } 56 | } -------------------------------------------------------------------------------- /packages/compiler-core/src/controller/if-scope.ts: -------------------------------------------------------------------------------- 1 | import type { Identifier, IfStatement, Statement } from '@babel/types'; 2 | import { getT, markMNR, traverseIfStatement } from '../parse-utils'; 3 | import { ControlScope } from './control-scope'; 4 | import { AlinsVar, ImportManager } from './import-manager'; 5 | import { createScopeStack } from './scope-stack'; 6 | 7 | /* 8 | * @Author: chenzhongsheng 9 | * @Date: 2023-07-14 17:39:29 10 | * @Description: Coding something 11 | */ 12 | 13 | 14 | export class IfScope extends ControlScope { 15 | 16 | static ScopeStack = createScopeStack(); 17 | 18 | _init () { 19 | IfScope.ScopeStack.newNode(this); 20 | const node = this.path.node; 21 | const map = traverseIfStatement(node); 22 | const t = getT(); 23 | 24 | let anchor = null; 25 | 26 | const end = map.end; 27 | 28 | const setAnchor = ( 29 | object: any, id: Identifier|null, args: any[], 30 | ) => { 31 | const bodyFn = args[args.length - 1]; 32 | if (!id || id.name !== 'end') { 33 | args[args.length - 1] = markMNR(bodyFn, () => { 34 | this.markScopeReturnJsx(); 35 | }); 36 | } else { 37 | end._mnr = (fn: any) => { 38 | args[args.length - 1] = markMNR(fn); 39 | }; 40 | } 41 | // @ts-ignore 42 | anchor = t.callExpression( 43 | id ? t.memberExpression(object, id) : object, 44 | args 45 | ); 46 | bodyFn._call = anchor; 47 | }; 48 | 49 | setAnchor(ImportManager.use(AlinsVar.If), null, [ map.if.test, map.if.fn ]); 50 | 51 | for (const item of map.elif) { 52 | setAnchor(anchor, item.id, [ item.test, item.fn ]); 53 | } 54 | 55 | if (map.else) { 56 | setAnchor(anchor, map.else.id, [ map.else.fn ]); 57 | } 58 | 59 | setAnchor(anchor, end.id, [ end.fn ]); 60 | 61 | this.replaceEnd = (nodes: Statement[]) => { 62 | const block = t.blockStatement(nodes); 63 | // 只要end有返回,则肯定有返回 64 | if (this.parentScope.awaitRecorded) { 65 | end.fn.body._setAsync?.(); 66 | } 67 | end.fn.body = block; 68 | // ! end 的 mnr 需要在结束的时候做 69 | end._mnr?.(end.fn); 70 | // @ts-ignore 71 | this.replaceEnd = null; 72 | }; 73 | 74 | if (!this.top) { 75 | // @ts-ignore 76 | anchor = t.returnStatement(anchor); 77 | } 78 | this.newNode = anchor; 79 | } 80 | 81 | exit () { 82 | IfScope.ScopeStack.pop(); 83 | return super.exit(); 84 | } 85 | } -------------------------------------------------------------------------------- /packages/compiler-core/src/controller/import-manager.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-09-06 11:35:21 4 | * @Description: Coding something 5 | */ 6 | 7 | import { getT } from '../parse-utils'; 8 | 9 | export type IImportType = 'esm' | 'cjs' | 'iife'; 10 | 11 | export const AlinsStr = { 12 | Prefix: '_$', 13 | Value: 'v', 14 | Temp: '_$R', 15 | Event: '$e' 16 | }; 17 | 18 | export enum AlinsVar { 19 | Create = 'ce', 20 | MNR = 'mnr', 21 | React = 'r', 22 | Computed = 'c', 23 | Watch = 'w', 24 | ComputedShort = 'cc', // computed 简写 25 | Extend = 'e', 26 | ExtendComp = 'es', 27 | MarkUpdate = 'mu', 28 | MockRef = 'mf', 29 | MockMap = 'mm', 30 | If = 'if', 31 | Switch = 'sw', 32 | Mount = 'mt', 33 | // 小写是为了与标签名保持一致 34 | appended = 'ad', 35 | mounted = 'md', 36 | created = 'cd', 37 | removed = 'rd', 38 | } 39 | 40 | // react | computed | watch | ComputedFull | 41 | 42 | export const ImportManager = (() => { 43 | let used = false; 44 | 45 | const useNames = new Set([]); 46 | 47 | let addUse: (name: AlinsVar)=>void = () => {}; 48 | 49 | let clear: any = () => {}; 50 | 51 | return { 52 | exitModule () { 53 | if (useNames.size === 0) { 54 | clear(); 55 | } 56 | useNames.clear(); 57 | addUse = () => {}; 58 | }, 59 | use (name: AlinsVar) { 60 | if (!used) used = true; 61 | const s = `${AlinsStr.Prefix}${name}`; 62 | if (!useNames.has(name)) { 63 | // @ts-ignore 64 | addUse(s); 65 | useNames.add(name); 66 | } 67 | return getT().identifier(s); 68 | }, 69 | init (type: IImportType, clearDecl: Function) { 70 | const t = getT(); 71 | clear = clearDecl; 72 | if (type === 'esm') { 73 | const declaration = t.importDeclaration([], t.stringLiteral('alins')); 74 | addUse = (name: AlinsVar) => { 75 | declaration.specifiers.push( 76 | t.importSpecifier(t.identifier(name), t.identifier(name)) 77 | ); 78 | }; 79 | return declaration; 80 | } else if (type === 'cjs' || type === 'iife') { 81 | const objectPattern = t.objectPattern([]); 82 | const target = type === 'iife' ? 83 | t.memberExpression(t.identifier('window'), t.identifier('Alins')) : 84 | t.callExpression(t.identifier('require'), [ t.stringLiteral('alins') ]); 85 | const declaration = t.variableDeclaration('var', [ t.variableDeclarator(objectPattern, target) ]); 86 | addUse = (name: AlinsVar) => { 87 | objectPattern.properties.push( 88 | t.objectProperty(t.identifier(name), t.identifier(name), false, true) 89 | ); 90 | }; 91 | return declaration; 92 | } else { 93 | throw new Error(`Unsupported import type "${type}"`); 94 | } 95 | } 96 | }; 97 | })(); -------------------------------------------------------------------------------- /packages/compiler-core/src/controller/scope-stack.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-08-19 14:01:37 4 | * @Description: Coding something 5 | */ 6 | export function createScopeStack () { 7 | const stack: T[] = []; 8 | 9 | return { 10 | pop () { 11 | return stack.pop(); 12 | }, 13 | newNode (node: T) { 14 | // @ts-ignore 15 | node.parent = this.getParent(); 16 | stack.push(node); 17 | }, 18 | getParent () { 19 | return stack[stack.length - 1] || null; 20 | } 21 | }; 22 | } -------------------------------------------------------------------------------- /packages/compiler-core/src/controller/static-scope.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-09-20 11:21:57 4 | * @Description: Coding something 5 | */ 6 | import { NodePath, Node } from '@babel/traverse'; 7 | import { parseCommentSingle, RegMap } from '../comment'; 8 | export class StaticScope { 9 | enable = false; 10 | check (path: NodePath) { 11 | if (this.enable) return; 12 | const node = path.node; 13 | 14 | const markStatic = () => { 15 | this.enable = true; 16 | // @ts-ignore 17 | node._isStaticScope = true; 18 | }; 19 | 20 | // @ts-ignore 21 | if (node._isStaticScope) { 22 | markStatic(); 23 | return; 24 | } 25 | 26 | const comment = parseCommentSingle(node, RegMap.StaticScope, true); 27 | if (comment) { 28 | markStatic(); 29 | return; 30 | } 31 | // ! 去除变量命名控制静态作用域 32 | // if (node.type === 'FunctionDeclaration') { 33 | // if (node.id?.name[0] === '_') markStatic(); 34 | // } else if ( 35 | // node.type === 'ArrowFunctionExpression' || 36 | // node.type === 'FunctionExpression' 37 | // ) { 38 | // if ( 39 | // path.parent.type === 'VariableDeclarator' && 40 | // // @ts-ignore 41 | // path.parent.id?.name[0] === '_' 42 | // ) { 43 | // markStatic(); 44 | // } 45 | // } 46 | } 47 | exit (node: any) { 48 | if (this.enable && node._isStaticScope) { 49 | this.enable = false; 50 | } 51 | } 52 | 53 | } -------------------------------------------------------------------------------- /packages/compiler-core/src/controller/switch-scope.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-07-14 17:39:29 4 | * @Description: Coding something 5 | */ 6 | import type { Statement, SwitchStatement } from '@babel/types'; 7 | import { getT, traverseSwitchStatement } from '../parse-utils'; 8 | 9 | import { ControlScope } from './control-scope'; 10 | import { createScopeStack } from './scope-stack'; 11 | 12 | export class SwitchScope extends ControlScope { 13 | 14 | static ScopeStack = createScopeStack(); 15 | 16 | _init () { 17 | SwitchScope.ScopeStack.newNode(this); 18 | const { endFunc, node, isReturnJsx } = traverseSwitchStatement(this.path.node); 19 | if (isReturnJsx) { 20 | this.markScopeReturnJsx(); 21 | } 22 | 23 | this.newNode = node; 24 | 25 | if (!this.top) { 26 | this.newNode = getT().returnStatement(this.newNode); 27 | } 28 | this.replaceEnd = (nodes: Statement[]) => { 29 | // 只要end有返回,则肯定有返回 30 | if (this.parentScope.awaitRecorded) { 31 | // @ts-ignore 32 | endFunc.body._setAsync?.(); 33 | } 34 | endFunc.body = getT().blockStatement(nodes); 35 | // @ts-ignore 36 | this.replaceEnd = null; 37 | }; 38 | } 39 | 40 | exit () { 41 | SwitchScope.ScopeStack.pop(); 42 | return super.exit(); 43 | } 44 | } -------------------------------------------------------------------------------- /packages/compiler-core/src/index.ts: -------------------------------------------------------------------------------- 1 | import { IImportType } from './controller/import-manager'; 2 | 3 | export type { IImportType } from './controller/import-manager'; 4 | /* 5 | * @Author: chenzhongsheng 6 | * @Date: 2023-07-11 14:11:47 7 | * @Description: Coding something 8 | */ 9 | export interface IParserOptions { 10 | importType?: IImportType; 11 | ts?: boolean; 12 | filename?: string; 13 | } 14 | 15 | export function randomTsxFileName () { 16 | return `${Math.random().toString(16).substring(2)}.tsx`; 17 | } 18 | 19 | export type IAlinsParser = (code: string, options?: IParserOptions) => string; 20 | 21 | export { createNodeVisitor, createBabelPluginAlins } from './transform'; 22 | 23 | // import type {Node} from '@babel/traverse'; 24 | 25 | // import * as A from '@babel/types'; 26 | 27 | // export const a: Node = {} as any; 28 | 29 | // export default A; -------------------------------------------------------------------------------- /packages/compiler-node/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | node_modules 3 | pnpm-lock.yaml -------------------------------------------------------------------------------- /packages/compiler-node/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2022 - present 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /packages/compiler-node/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "alins-compiler-node", 3 | "version": "0.0.36", 4 | "description": "All-in-js Web UI Framework, No jsx/template/vdom/css/html", 5 | "main": "src/index.ts", 6 | "typings": "src/index.ts", 7 | "repository": "git@github.com:alinsjs/alins.git", 8 | "author": "tackchen ", 9 | "scripts": { 10 | "build": "node ../../scripts/build/build.js compiler-node" 11 | }, 12 | "keywords": [ 13 | "alins", 14 | "all-in-js", 15 | "alins-style", 16 | "css-in-js", 17 | "web-ui-framework" 18 | ], 19 | "license": "MIT", 20 | "type": "commonjs", 21 | "publishConfig": { 22 | "registry": "https://registry.npmjs.org/" 23 | }, 24 | "dependencies": { 25 | "@babel/core": "^7.22.9", 26 | "@babel/preset-react": "^7.22.5", 27 | "@babel/preset-typescript": "^7.22.5", 28 | "alins-compiler-core": "^0.0.36" 29 | }, 30 | "module": "src/index.ts" 31 | } -------------------------------------------------------------------------------- /packages/compiler-node/src/extend.d.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-08-05 14:08:33 4 | * @Description: Coding something 5 | */ 6 | declare module '@babel/core' { 7 | const transform: any; 8 | } 9 | declare module '@babel/preset-react' { 10 | const preset: any; 11 | } -------------------------------------------------------------------------------- /packages/compiler-node/src/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 4 | * @Description: Coding something 5 | */ 6 | import { transform } from '@babel/core'; 7 | import { createBabelPluginAlins, IParserOptions, randomTsxFileName } from 'alins-compiler-core'; 8 | import react from '@babel/preset-react'; 9 | import typescript from '@babel/preset-react'; 10 | 11 | export { IParserOptions } from 'alins-compiler-core'; 12 | 13 | export function parseAlins (code: string, { 14 | ts, importType, filename 15 | }: IParserOptions = {}): string { 16 | 17 | const options = { 18 | sourceMaps: false, 19 | presets: [ react ], 20 | plugins: [ [ createBabelPluginAlins(), { importType } ] ], 21 | }; 22 | 23 | if (ts) { 24 | options.presets.push(typescript); 25 | // @ts-ignore 26 | options.filename = filename || randomTsxFileName(); 27 | } else { 28 | // @ts-ignore 29 | if (filename) options.filename = filename; 30 | } 31 | 32 | const output = transform(code, options); 33 | return output.code || ''; 34 | } -------------------------------------------------------------------------------- /packages/compiler-web/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | node_modules 3 | pnpm-lock.yaml -------------------------------------------------------------------------------- /packages/compiler-web/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2022 - present 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /packages/compiler-web/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "alins-compiler-web", 3 | "version": "0.0.36", 4 | "description": "All-in-js Web UI Framework, No jsx/template/vdom/css/html", 5 | "main": "src/index.ts", 6 | "typings": "src/index.ts", 7 | "repository": "git@github.com:alinsjs/alins.git", 8 | "author": "tackchen ", 9 | "scripts": { 10 | "build": "node ../../scripts/build/build.js compiler-web" 11 | }, 12 | "keywords": [ 13 | "alins", 14 | "all-in-js", 15 | "alins-style", 16 | "css-in-js", 17 | "web-ui-framework" 18 | ], 19 | "license": "MIT", 20 | "publishConfig": { 21 | "registry": "https://registry.npmjs.org/" 22 | }, 23 | "dependencies": { 24 | "alins": "^0.0.36", 25 | "alins-compiler-core": "^0.0.36" 26 | }, 27 | "module": "src/index.ts", 28 | "unpkg": "dist/alins-compiler-web.iife.min.js", 29 | "jsdelivr": "dist/alins-compiler-web.iife.min.js" 30 | } -------------------------------------------------------------------------------- /packages/compiler-web/src/babel.min.d.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-09-06 16:20:04 4 | * @Description: Coding something 5 | */ 6 | // ! 模改babel-standalone 目的是为了去掉babel内部自动执行 text/babel 的逻辑 7 | 8 | declare const Babel: { 9 | transform(code: string, options: any): {code: string}; 10 | registerPlugin(name: string, plugin: any): void; 11 | }; 12 | 13 | export default Babel; -------------------------------------------------------------------------------- /packages/compiler-web/src/boot.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-07-11 11:53:54 4 | * @Description: Coding something 5 | */ 6 | 7 | import { 8 | _$c, _$cc, _$ce, _$e, _$es, _$if, _$mf, _$mm, _$mnr, 9 | _$mu, _$r, _$sw, _$w, _$mt, 10 | _$ad, _$cd, _$md, _$rd, 11 | version, createStore, 12 | defineRenderer, useRenderer, 13 | ref, reactive, computed, watch, observe, 14 | mount, mounted, removed, created, appended, 15 | } from 'alins'; 16 | import { parseWebAlins } from './parser'; 17 | import { IImportType } from 'alins-compiler-core'; 18 | 19 | function onDOMContentLoaded () { 20 | const names = [ 'alins', 'babel', 'jsx' ]; 21 | for (const name of names) { 22 | const scripts = document.querySelectorAll(`script[type="text/${name}"]`); 23 | // @ts-ignore 24 | for (const item of scripts) { 25 | // @ts-ignore 26 | onSingleScript(item, item.getAttribute('import') || 'iife', item.hasAttribute('ts')); 27 | } 28 | } 29 | } 30 | 31 | async function onSingleScript (script: HTMLScriptElement, importType: IImportType = 'iife', ts = false) { 32 | // __DEV__ && console.log(`web=${web}; ts=${ts}`); 33 | let code = ''; 34 | if (script.innerText.trim() === '') { 35 | if (script.src) { 36 | const result = await fetch(script.src); 37 | if (result.status === 200) { 38 | code = await result.text(); 39 | } else { 40 | throw new Error(result.statusText); 41 | } 42 | } 43 | } else { 44 | code = script.innerText; 45 | } 46 | const output = parseWebAlins(code, { importType, ts }); 47 | // console.warn(code); 48 | // console.warn('============>'); 49 | if (__DEV__) console.warn('Compiler output:', output); 50 | if (output) { 51 | // exeJs(output); 52 | const script = document.createElement('script'); 53 | script.textContent = output; 54 | // script.innerHTML = output; 55 | document.head.appendChild(script); 56 | } 57 | } 58 | 59 | if (typeof window !== 'undefined') { 60 | // @ts-ignore 61 | window.Alins = { 62 | _$c, _$cc, _$ce, _$e, _$es, _$mf, _$mm, _$mnr, _$mt, 63 | _$mu, _$r, _$sw, _$w, _$if, version, createStore, 64 | _$ad, _$cd, _$md, _$rd, 65 | useRenderer, 66 | defineRenderer, 67 | ref, reactive, computed, watch, observe, 68 | mount, mounted, removed, created, appended, 69 | }; 70 | window.addEventListener('DOMContentLoaded', onDOMContentLoaded, false); 71 | } 72 | 73 | // function exeJs (code) { 74 | // const blob = new Blob([ code ], {type: 'text/javascript'}); 75 | // const objectURL = window.URL.createObjectURL(blob); 76 | // const script = document.createElement('script'); 77 | // script.onload = () => { 78 | // console.log('loaded'); 79 | // }; 80 | // script.src = objectURL; 81 | // document.head.appendChild(script); 82 | // } 83 | -------------------------------------------------------------------------------- /packages/compiler-web/src/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-08-02 23:19:55 4 | * @Description: Coding something 5 | */ 6 | import './boot'; 7 | export * from './parser'; -------------------------------------------------------------------------------- /packages/compiler-web/src/parser.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-07-11 14:35:14 4 | * @Description: Coding something 5 | */ 6 | // ! 模改babel-standalone 目的是为了去掉babel内部自动执行 text/babel 的逻辑 7 | import Babel from './babel.min'; 8 | import { createBabelPluginAlins, IParserOptions, randomTsxFileName } from 'alins-compiler-core'; 9 | 10 | Babel.registerPlugin('alins', createBabelPluginAlins()); 11 | 12 | export function parseWebAlins (code: string, { 13 | ts, importType, filename 14 | }: IParserOptions = { importType: 'iife' }): string { 15 | const options = { 16 | sourceMaps: false, 17 | presets: [ 'react' ], 18 | plugins: [ [ 'alins', { importType } ] ], 19 | }; 20 | if (ts) { 21 | options.presets.push('typescript'); 22 | // @ts-ignore 23 | options.filename = filename || randomTsxFileName(); 24 | } 25 | const output = Babel.transform(code, options); 26 | return output.code || ''; 27 | } 28 | -------------------------------------------------------------------------------- /packages/plugin-babel-preset/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | node_modules 3 | pnpm-lock.yaml -------------------------------------------------------------------------------- /packages/plugin-babel-preset/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2022 - present 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /packages/plugin-babel-preset/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "babel-preset-alins", 3 | "version": "0.0.36", 4 | "description": "All-in-js Web UI Framework, No jsx/template/vdom/css/html", 5 | "main": "src/index.ts", 6 | "typings": "src/index.ts", 7 | "repository": "git@github.com:alinsjs/alins.git", 8 | "author": "tackchen ", 9 | "scripts": { 10 | "build": "node ../../scripts/build/build.js plugin-babel-preset" 11 | }, 12 | "keywords": [ 13 | "alins", 14 | "all-in-js", 15 | "alins-style", 16 | "css-in-js", 17 | "web-ui-framework" 18 | ], 19 | "license": "MIT", 20 | "type": "commonjs", 21 | "publishConfig": { 22 | "registry": "https://registry.npmjs.org/" 23 | }, 24 | "dependencies": { 25 | "@babel/preset-react": "^7.22.5", 26 | "@babel/preset-typescript": "^7.22.5", 27 | "babel-plugin-alins": "^0.0.36" 28 | }, 29 | "module": "src/index.ts" 30 | } -------------------------------------------------------------------------------- /packages/plugin-babel-preset/src/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-08-02 22:36:16 4 | * @Description: Coding something 5 | */ 6 | export default function (babel: any, { 7 | importType, ts, jsx 8 | }: { 9 | importType?: 'cjs' | 'esm' | 'iife'; 10 | ts?: boolean; 11 | jsx?: boolean 12 | }) { 13 | const presets: any[] = []; 14 | if (ts) { 15 | presets.push(require('@babel/preset-typescript')); 16 | } 17 | if (jsx !== false) { 18 | presets.push(require('@babel/preset-react')); 19 | } 20 | return { 21 | plugins: [ [ 22 | require('babel-plugin-alins'), { importType } 23 | ] ], 24 | presets, 25 | }; 26 | } -------------------------------------------------------------------------------- /packages/plugin-babel/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | node_modules 3 | pnpm-lock.yaml -------------------------------------------------------------------------------- /packages/plugin-babel/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2022 - present 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /packages/plugin-babel/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "babel-plugin-alins", 3 | "version": "0.0.36", 4 | "description": "All-in-js Web UI Framework, No jsx/template/vdom/css/html", 5 | "main": "src/index.ts", 6 | "typings": "src/index.ts", 7 | "repository": "git@github.com:alinsjs/alins.git", 8 | "author": "tackchen ", 9 | "scripts": { 10 | "build": "node ../../scripts/build/build.js plugin-babel" 11 | }, 12 | "keywords": [ 13 | "alins", 14 | "all-in-js", 15 | "alins-style", 16 | "css-in-js", 17 | "web-ui-framework" 18 | ], 19 | "license": "MIT", 20 | "type": "commonjs", 21 | "publishConfig": { 22 | "registry": "https://registry.npmjs.org/" 23 | }, 24 | "dependencies": { 25 | "alins-compiler-core": "^0.0.36" 26 | }, 27 | "module": "src/index.ts" 28 | } -------------------------------------------------------------------------------- /packages/plugin-babel/src/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-08-02 22:36:16 4 | * @Description: Coding something 5 | */ 6 | import { createBabelPluginAlins, IImportType } from 'alins-compiler-core'; 7 | 8 | // @ts-ignore 9 | const plugin: (data: any, args?: {importType?: IImportType}) => { 10 | name: string; 11 | visitor: any; 12 | } = createBabelPluginAlins(); 13 | 14 | export default plugin; -------------------------------------------------------------------------------- /packages/plugin-esbuild/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | node_modules 3 | pnpm-lock.yaml -------------------------------------------------------------------------------- /packages/plugin-esbuild/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2022 - present 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /packages/plugin-esbuild/README.md: -------------------------------------------------------------------------------- 1 | 6 | 7 |

8 | 9 |

10 | 11 |

12 | 13 | stars 14 | 15 | 16 | forks 17 | 18 | 19 | version 20 | 21 | 22 | downloads 23 | 24 | 25 | jsdelivr 26 | 27 | visitors 28 |

29 | 30 |

31 | 32 | author 33 | 34 | 35 | license 36 | 37 | Size 38 | TopLang 39 | issue 40 | Dependent 41 |

42 | 43 | ## 🚀 [Alins](https://github.com/alinsjs/alins): The most pure and elegant WebUI framework 44 | 45 | **[中文](https://github.com/alinsjs/alins/blob/master/README.cn.md) | [Documentation](https://alinsjs.github.io/docs) | [Playground](https://alinsjs.github.io/playground/) | [Update Log](https://github.com/alinsjs/alins/blob/master/scripts/helper/version.md) | [Feedback Errors/Defects](https://github.com/alinsjs/alins/issues/new) | [Gitee](https://gitee.com/alinsjs/alins) | [Message Board](https://theajack.github.io/message-board/?app=alins)** 46 | 47 | ## [esbuild-plugin-alins](https://www.npmjs.com/package/esbuild-plugin-alins) 48 | 49 | ```js 50 | import { build } from 'esbuild' 51 | import alins from 'esbuild-plugin-alins' 52 | 53 | build({ 54 | plugins: [alins()], 55 | }); 56 | ``` 57 | 58 | Note: Alins will compile files named with `jsx` and `tsx` suffixes by default. -------------------------------------------------------------------------------- /packages/plugin-esbuild/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "esbuild-plugin-alins", 3 | "version": "0.0.36", 4 | "description": "All-in-js Web UI Framework, No jsx/template/vdom/css/html", 5 | "main": "src/index.ts", 6 | "typings": "src/index.ts", 7 | "repository": "git@github.com:alinsjs/alins.git", 8 | "author": "tackchen ", 9 | "scripts": { 10 | "build": "node ../../scripts/build/build.js plugin-esbuild" 11 | }, 12 | "keywords": [ 13 | "alins", 14 | "all-in-js", 15 | "alins-style", 16 | "css-in-js", 17 | "web-ui-framework" 18 | ], 19 | "license": "MIT", 20 | "type": "commonjs", 21 | "publishConfig": { 22 | "registry": "https://registry.npmjs.org/" 23 | }, 24 | "dependencies": { 25 | "alins-compiler-node": "^0.0.36" 26 | }, 27 | "module": "src/index.ts" 28 | } -------------------------------------------------------------------------------- /packages/plugin-esbuild/src/index.ts: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * @Author: chenzhongsheng 4 | * @Date: 2022-11-25 10:45:54 5 | * @Description: Coding something 6 | */ 7 | import {parseAlins} from 'alins-compiler-node'; 8 | import fs from 'fs'; 9 | 10 | export default () => { 11 | return { 12 | name: 'alins', 13 | setup (build: any) { 14 | // console.log('build', build); 15 | 16 | const compile = async (args: any, ts = false) => { 17 | let source = await fs.promises.readFile(args.path, 'utf8'); 18 | // console.log('esbuild-plugin-start', source); 19 | if (ts) { 20 | // ! 此处使用自带的esbuild 21 | source = build.esbuild.transformSync(source, { 22 | // loader: 'tsx', 23 | // jsx: 'preserve', 24 | loader: 'ts', // todo 验证只使用 ts是否可行 25 | }).code; 26 | // console.log('esbuild-plugin-ts-result', source); 27 | } 28 | // console.log('esbuild-plugin-alins', source); 29 | const result = parseAlins(source); 30 | // console.log('esbuild-plugin-alins', result); 31 | return { 32 | contents: result, 33 | loader: 'js' 34 | }; 35 | }; 36 | build.onLoad({filter: /\.tsx$/}, (args: any) => { 37 | // console.log('onLoad tsx'); 38 | return compile(args, true); 39 | }); 40 | build.onLoad({filter: /\.jsx$/}, (args: any) => { 41 | return compile(args); 42 | }); 43 | } 44 | }; 45 | }; -------------------------------------------------------------------------------- /packages/plugin-eslint/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | node_modules 3 | pnpm-lock.yaml -------------------------------------------------------------------------------- /packages/plugin-eslint/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2022 - present 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /packages/plugin-eslint/README.md: -------------------------------------------------------------------------------- 1 | 6 | 7 |

8 | 9 |

10 | 11 |

12 | 13 | stars 14 | 15 | 16 | forks 17 | 18 | 19 | version 20 | 21 | 22 | downloads 23 | 24 | 25 | jsdelivr 26 | 27 | visitors 28 |

29 | 30 |

31 | 32 | author 33 | 34 | 35 | license 36 | 37 | Size 38 | TopLang 39 | issue 40 | Dependent 41 |

42 | 43 | ## 🚀 [Alins](https://github.com/alinsjs/alins): The most pure and elegant WebUI framework 44 | 45 | **[中文](https://github.com/alinsjs/alins/blob/master/README.cn.md) | [Documentation](https://alinsjs.github.io/docs) | [Playground](https://alinsjs.github.io/playground/) | [Update Log](https://github.com/alinsjs/alins/blob/master/scripts/helper/version.md) | [Feedback Errors/Defects](https://github.com/alinsjs/alins/issues/new) | [Gitee](https://gitee.com/alinsjs/alins) | [Message Board](https://theajack.github.io/message-board/?app=alins)** 46 | 47 | ## [eslint-config-alins](https://www.npmjs.com/package/eslint-config-alins) 48 | 49 | Alins eslint config module, after installation, configure it in the .eslintrc file: 50 | 51 | ```js 52 | { 53 | "extends": "alins" 54 | } 55 | ``` -------------------------------------------------------------------------------- /packages/plugin-eslint/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-08-03 10:42:51 4 | * @Description: Coding something 5 | */ 6 | module.exports = { 7 | plugins: [ 'eslint-plugin-react' ], 8 | 'globals': { 9 | 'For': true, 10 | 'Switch': true, 11 | 'Case': true, 12 | 'Default': true, 13 | 'If': true, 14 | 'ElseIf': true, 15 | 'Else': true, 16 | 'Async': true, 17 | 'Show': true, 18 | '$item': true, 19 | '$index': true, 20 | '$data': true, 21 | '$e': true, 22 | 'React': true, 23 | }, 24 | }; -------------------------------------------------------------------------------- /packages/plugin-eslint/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "eslint-config-alins", 3 | "version": "0.0.36", 4 | "description": "All-in-js Web UI Framework, No jsx/template/vdom/css/html", 5 | "main": "src/index.ts", 6 | "repository": "git@github.com:alinsjs/alins.git", 7 | "author": "tackchen ", 8 | "scripts": { 9 | "build": "node ../../scripts/build/build.js plugin-eslint" 10 | }, 11 | "keywords": [ 12 | "alins", 13 | "all-in-js", 14 | "alins-style", 15 | "css-in-js", 16 | "web-ui-framework" 17 | ], 18 | "license": "MIT", 19 | "type": "commonjs", 20 | "publishConfig": { 21 | "registry": "https://registry.npmjs.org/" 22 | }, 23 | "dependencies": { 24 | "@typescript-eslint/parser": "^6.3.0", 25 | "eslint-plugin-react": "^7.33.1" 26 | }, 27 | "typings": "src/index.ts", 28 | "module": "src/index.ts" 29 | } -------------------------------------------------------------------------------- /packages/plugin-eslint/ts.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | parser: '@typescript-eslint/parser', 3 | plugins: [ 'eslint-plugin-react' ], 4 | 'globals': { 5 | 'For': true, 6 | 'Switch': true, 7 | 'Case': true, 8 | 'Default': true, 9 | 'If': true, 10 | 'ElseIf': true, 11 | 'Else': true, 12 | 'Async': true, 13 | 'Show': true, 14 | '$item': true, 15 | '$index': true, 16 | '$data': true, 17 | 'React': true, 18 | }, 19 | }; -------------------------------------------------------------------------------- /packages/plugin-rollup/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | node_modules 3 | pnpm-lock.yaml -------------------------------------------------------------------------------- /packages/plugin-rollup/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2022 - present 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /packages/plugin-rollup/README.md: -------------------------------------------------------------------------------- 1 | 2 |

3 | 4 |

5 | 6 |

7 | 8 | stars 9 | 10 | 11 | forks 12 | 13 | 14 | version 15 | 16 | 17 | downloads 18 | 19 | 20 | jsdelivr 21 | 22 | visitors 23 |

24 | 25 |

26 | 27 | author 28 | 29 | 30 | license 31 | 32 | Size 33 | TopLang 34 | issue 35 | Dependent 36 |

37 | 38 | ## 🚀 [Alins](https://github.com/alinsjs/alins): The most pure and elegant WebUI framework 39 | 40 | **[中文](https://github.com/alinsjs/alins/blob/master/README.cn.md) | [Documentation](https://alinsjs.github.io/docs) | [Playground](https://alinsjs.github.io/playground/) | [Update Log](https://github.com/alinsjs/alins/blob/master/scripts/helper/version.md) | [Feedback Errors/Defects](https://github.com/alinsjs/alins/issues/new) | [Gitee](https://gitee.com/alinsjs/alins) | [Message Board](https://theajack.github.io/message-board/?app=alins)** 41 | 42 | ## [rollup-plugin-alins](https://www.npmjs.com/package/rollup-plugin-alins) 43 | 44 | ```js 45 | // rollup.config.js 46 | import alins from 'rollup-plugin-alins' 47 | 48 | export default { 49 | plugins: [ 50 | alins() 51 | ] 52 | } 53 | ``` 54 | 55 | Note: Alins will compile files named with `jsx` and `tsx` suffixes by default. -------------------------------------------------------------------------------- /packages/plugin-rollup/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rollup-plugin-alins", 3 | "version": "0.0.36", 4 | "description": "All-in-js Web UI Framework, No jsx/template/vdom/css/html", 5 | "main": "src/index.ts", 6 | "typings": "src/index.ts", 7 | "repository": "git@github.com:alinsjs/alins.git", 8 | "author": "tackchen ", 9 | "scripts": { 10 | "build": "node ../../scripts/build/build.js plugin-rollup" 11 | }, 12 | "keywords": [ 13 | "alins", 14 | "all-in-js", 15 | "alins-style", 16 | "css-in-js", 17 | "web-ui-framework" 18 | ], 19 | "license": "MIT", 20 | "type": "commonjs", 21 | "publishConfig": { 22 | "registry": "https://registry.npmjs.org/" 23 | }, 24 | "dependencies": { 25 | "alins-compiler-node": "^0.0.36" 26 | }, 27 | "module": "src/index.ts" 28 | } -------------------------------------------------------------------------------- /packages/plugin-rollup/src/index.ts: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * @Author: chenzhongsheng 4 | * @Date: 2022-11-25 10:45:54 5 | * @Description: Coding something 6 | */ 7 | import {IParserOptions, parseAlins} from 'alins-compiler-node'; 8 | 9 | export default function rollupPluginAlins () { 10 | return { 11 | name: 'alins', 12 | transform (source: string, id: string) { 13 | if (!/\.[jt]sx$/.test(id)) return source; 14 | // console.log('rollup 1-----', source); 15 | 16 | const options: IParserOptions = { 17 | filename: id 18 | }; 19 | 20 | if (/\.tsx$/.test(id)) { 21 | options.ts = true; 22 | } 23 | // console.log('rollup 2-----', source); 24 | const result = parseAlins(source); 25 | // console.log('rollup 3-----', result); 26 | return result; 27 | }, 28 | }; 29 | } -------------------------------------------------------------------------------- /packages/plugin-vite/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | node_modules 3 | pnpm-lock.yaml -------------------------------------------------------------------------------- /packages/plugin-vite/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2022 - present 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /packages/plugin-vite/README.md: -------------------------------------------------------------------------------- 1 | 2 |

3 | 4 |

5 | 6 |

7 | 8 | stars 9 | 10 | 11 | forks 12 | 13 | 14 | version 15 | 16 | 17 | downloads 18 | 19 | 20 | jsdelivr 21 | 22 | visitors 23 |

24 | 25 |

26 | 27 | author 28 | 29 | 30 | license 31 | 32 | Size 33 | TopLang 34 | issue 35 | Dependent 36 |

37 | 38 | ## 🚀 [Alins](https://github.com/alinsjs/alins): The most pure and elegant WebUI framework 39 | 40 | **[中文](https://github.com/alinsjs/alins/blob/master/README.cn.md) | [Documentation](https://alinsjs.github.io/docs) | [Playground](https://alinsjs.github.io/playground/) | [Update Log](https://github.com/alinsjs/alins/blob/master/scripts/helper/version.md) | [Feedback Errors/Defects](https://github.com/alinsjs/alins/issues/new) | [Gitee](https://gitee.com/alinsjs/alins) | [Message Board](https://theajack.github.io/message-board/?app=alins)** 41 | 42 | ## [vite-plugin-alins](https://www.npmjs.com/package/vite-plugin-alins) 43 | 44 | ```js 45 | // vite.config.js 46 | import { defineConfig } from 'vite' 47 | import alins from 'vite-plugin-alins' 48 | 49 | export default defineConfig({ 50 | plugins: [alins()], 51 | }) 52 | ``` 53 | 54 | Note: Alins will compile files named with `jsx` and `tsx` suffixes by default. -------------------------------------------------------------------------------- /packages/plugin-vite/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vite-plugin-alins", 3 | "version": "0.0.36", 4 | "description": "All-in-js Web UI Framework, No jsx/template/vdom/css/html", 5 | "main": "src/index.ts", 6 | "typings": "src/index.ts", 7 | "repository": "git@github.com:alinsjs/alins.git", 8 | "author": "tackchen ", 9 | "scripts": { 10 | "build": "node ../../scripts/build/build.js plugin-vite" 11 | }, 12 | "keywords": [ 13 | "alins", 14 | "all-in-js", 15 | "alins-style", 16 | "css-in-js", 17 | "web-ui-framework" 18 | ], 19 | "license": "MIT", 20 | "type": "commonjs", 21 | "publishConfig": { 22 | "registry": "https://registry.npmjs.org/" 23 | }, 24 | "dependencies": { 25 | "alins-compiler-node": "^0.0.36" 26 | }, 27 | "module": "src/index.ts" 28 | } -------------------------------------------------------------------------------- /packages/plugin-vite/src/index.ts: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * @Author: chenzhongsheng 4 | * @Date: 2022-11-25 10:45:54 5 | * @Description: Coding something 6 | */ 7 | import {parseAlins} from 'alins-compiler-node'; 8 | 9 | export default function AlinsVitePlugin () { 10 | return { 11 | name: 'alins', 12 | 13 | config: () => ({ 14 | esbuild: { 15 | jsx: 'preserve' 16 | } 17 | }) as any, 18 | 19 | transform (code: string, id: string) { 20 | if (!/\.[jt]sx$/.test(id)) return null; 21 | return {code: parseAlins(code)}; 22 | }, 23 | }; 24 | } 25 | -------------------------------------------------------------------------------- /packages/plugin-webpack/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | node_modules 3 | pnpm-lock.yaml -------------------------------------------------------------------------------- /packages/plugin-webpack/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2022 - present 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /packages/plugin-webpack/README.md: -------------------------------------------------------------------------------- 1 | 6 | 7 |

8 | 9 |

10 | 11 |

12 | 13 | stars 14 | 15 | 16 | forks 17 | 18 | 19 | version 20 | 21 | 22 | downloads 23 | 24 | 25 | jsdelivr 26 | 27 | visitors 28 |

29 | 30 |

31 | 32 | author 33 | 34 | 35 | license 36 | 37 | Size 38 | TopLang 39 | issue 40 | Dependent 41 |

42 | 43 | ## 🚀 [Alins](https://github.com/alinsjs/alins): The most pure and elegant WebUI framework 44 | 45 | **[中文](https://github.com/alinsjs/alins/blob/master/README.cn.md) | [Documentation](https://alinsjs.github.io/docs) | [Playground](https://alinsjs.github.io/playground/) | [Update Log](https://github.com/alinsjs/alins/blob/master/scripts/helper/version.md) | [Feedback Errors/Defects](https://github.com/alinsjs/alins/issues/new) | [Gitee](https://gitee.com/alinsjs/alins) | [Message Board](https://theajack.github.io/message-board/?app=alins)** 46 | 47 | ## [alins-loader](https://www.npmjs.com/package/alins-loader) 48 | 49 | ```js 50 | module.exports = { 51 | module: { 52 | rules: [{ 53 | test: /\.[jt]sx$/, 54 | use: [ 55 | {loader: 'alins-loader'}, 56 | ] 57 | }] 58 | } 59 | }; 60 | ``` -------------------------------------------------------------------------------- /packages/plugin-webpack/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "alins-loader", 3 | "version": "0.0.36", 4 | "description": "All-in-js Web UI Framework, No jsx/template/vdom/css/html", 5 | "main": "src/index.ts", 6 | "typings": "src/index.ts", 7 | "repository": "git@github.com:alinsjs/alins.git", 8 | "author": "tackchen ", 9 | "scripts": { 10 | "build": "node ../../scripts/build/build.js plugin-webpack" 11 | }, 12 | "keywords": [ 13 | "alins", 14 | "all-in-js", 15 | "alins-style", 16 | "css-in-js", 17 | "web-ui-framework" 18 | ], 19 | "license": "MIT", 20 | "type": "commonjs", 21 | "publishConfig": { 22 | "registry": "https://registry.npmjs.org/" 23 | }, 24 | "dependencies": { 25 | "alins-compiler-node": "^0.0.36" 26 | }, 27 | "module": "src/index.ts" 28 | } -------------------------------------------------------------------------------- /packages/plugin-webpack/src/index.ts: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * @Author: chenzhongsheng 4 | * @Date: 2022-11-25 10:45:54 5 | * @Description: Coding something 6 | */ 7 | import {parseAlins, IParserOptions} from 'alins-compiler-node'; 8 | // import {parseAlins} from 'alins-compiler-node/dist/alins-compiler-node.umd.min'; 9 | 10 | export default function AlinsLoader (this: any, source: string) { 11 | const id = this.resourcePath; 12 | // console.log('this.resourcePath', id); 13 | if (!/\.[jt]sx$/.test(id)) return source; 14 | // console.log('AlinsLoader', source, id); 15 | 16 | const options: IParserOptions = { 17 | filename: id 18 | }; 19 | if (/\.tsx$/.test(id)) { 20 | options.ts = true; 21 | } 22 | const result = parseAlins(source, options); 23 | // console.log('AlinsLoader22', result); 24 | return result; 25 | } 26 | -------------------------------------------------------------------------------- /scripts/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alinsjs/alins/80dac471deebb96cda1c4b94860deab65ad674ec/scripts/.DS_Store -------------------------------------------------------------------------------- /scripts/a.html: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | 10 | 11 | Document 12 | 13 | 14 | 15 | 16 | 28 | 29 | -------------------------------------------------------------------------------- /scripts/build/babel.config.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-02-04 10:31:48 4 | * @Description: Coding something 5 | */ 6 | module.exports = { 7 | plugins: [ 'babel-plugin-replace-ts-export-assignment' ], 8 | presets: [ 9 | [ 10 | '@babel/preset-env', 11 | { 12 | useBuiltIns: 'entry', 13 | targets: { 14 | esmodules: true, 15 | ie: 11, 16 | }, 17 | }, 18 | ], 19 | '@babel/preset-typescript', 20 | ], 21 | }; 22 | 23 | -------------------------------------------------------------------------------- /scripts/build/build-multi.js: -------------------------------------------------------------------------------- 1 | const {execSync} = require('child_process'); 2 | 3 | /* 4 | * @Author: chenzhongsheng 5 | * @Date: 2023-08-09 21:23:17 6 | * @Description: Coding something 7 | */ 8 | const packages = process.argv.slice(2); 9 | console.log(packages); 10 | 11 | for (const name of packages) { 12 | console.log(`Start build: ${name}`); 13 | execSync(`npm run buildsingle ${name}`); 14 | } -------------------------------------------------------------------------------- /scripts/build/build.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: tackchen 3 | * @Date: 2022-10-23 20:12:31 4 | * @Description: Coding something 5 | */ 6 | 7 | const execa = require('execa'); 8 | const { resolveRootPath } = require('./utils'); 9 | 10 | const dirName = process.argv[2]; 11 | const env = process.argv[3] || 'prod'; 12 | 13 | async function build () { 14 | await execa( 15 | resolveRootPath('node_modules/rollup/dist/bin/rollup'), 16 | [ 17 | '-c', 18 | resolveRootPath('scripts/build/rollup.config.js'), 19 | '--environment', 20 | [ 21 | `DIR_NAME:${dirName}`, 22 | `ENV:${env}` 23 | ], 24 | ], 25 | { stdio: 'inherit' }, 26 | ); 27 | } 28 | 29 | async function main () { 30 | await build(); 31 | 32 | // ! 放在后面做 否则会build失败 33 | // initSinglePackageInfo(dirName, false); 34 | } 35 | 36 | main(); 37 | 38 | 39 | -------------------------------------------------------------------------------- /scripts/build/export-assign.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-08-05 14:18:12 4 | * @Description: Coding something 5 | */ 6 | 7 | 8 | const babelPluginReplaceTsExportAssignment = ({ 9 | template, 10 | }) => { 11 | const moduleExportsDeclaration = template(` 12 | module.exports = ASSIGNMENT; 13 | `); 14 | 15 | return { 16 | name: 'replace-ts-export-assignment', 17 | visitor: { 18 | TSExportAssignment (path) { 19 | path.replaceWith( 20 | moduleExportsDeclaration({ASSIGNMENT: path.node.expression}) 21 | ); 22 | }, 23 | }, 24 | }; 25 | }; 26 | 27 | module.exports = babelPluginReplaceTsExportAssignment; -------------------------------------------------------------------------------- /scripts/build/mod-package.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2022-10-31 09:17:58 4 | * @Description: Coding something 5 | */ 6 | const {initPackageInfo} = require('./utils'); 7 | 8 | initPackageInfo(); -------------------------------------------------------------------------------- /scripts/build/style-all-cdn.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2022-10-31 08:16:24 4 | * @Description: Coding something 5 | */ 6 | export * from '../../packages/core/src/index'; 7 | // 消除version重复 8 | export { 9 | css, 10 | style, 11 | pseudo, hover, active, before, after, nthChild, 12 | StyleAtoms, 13 | react, $ 14 | } from '../../packages/style/src/index'; 15 | 16 | export {useAdoptedStyle} from '../../packages/style/src/utils'; -------------------------------------------------------------------------------- /scripts/clear-dist.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-08-13 17:02:07 4 | * @Description: Coding something 5 | */ 6 | const fs = require('fs'); 7 | const path = require('path'); 8 | 9 | const pkgPath = path.resolve(__dirname, '../packages'); 10 | 11 | const pkgs = fs.readdirSync(pkgPath); 12 | 13 | pkgs.forEach(name => { 14 | if (name === '.DS_Store') return; 15 | const dirName = path.resolve(pkgPath, `./${name}/dist`); 16 | if (!fs.existsSync(dirName)) return; 17 | 18 | const files = fs.readdirSync(dirName); 19 | 20 | files.forEach(file => { 21 | fs.rmSync(path.resolve(dirName, file)); 22 | }); 23 | 24 | fs.rmdirSync(dirName); 25 | }); -------------------------------------------------------------------------------- /scripts/dev.js: -------------------------------------------------------------------------------- 1 | /* 2 | import default from './test/cases/async'; 3 | * @Author: chenzhongsheng 4 | * @Date: 2022-10-24 10:31:38 5 | * @Description: Coding something 6 | */ 7 | const esbuild = require('esbuild'); 8 | const { resolveRootPath } = require('./helper/utils'); 9 | const fs = require('fs'); 10 | 11 | const mode = process.argv[2] || 'dev_web'; 12 | 13 | const entry = ({ 14 | dev_node: 'scripts/dev/dev-node.ts', 15 | test_compiler_node: 'scripts/test/compiler/node.ts', 16 | test_compiler_web: 'scripts/test/compiler/web.ts', 17 | dev_web: 'scripts/dev/dev-web-compiler.ts', 18 | dev_web_standalone: 'scripts/dev/dev-web-standalone.ts', 19 | test_web: 'scripts/test/client/index.ts', 20 | })[mode]; 21 | 22 | if (mode === 'dev_web') { 23 | const files = fs.readdirSync(resolveRootPath('scripts/dev/samples')); 24 | fs.writeFileSync(resolveRootPath('scripts/dev/samples-list.ts'), `export default ${JSON.stringify(files)};`, 'utf8'); 25 | } 26 | 27 | main( 28 | resolveRootPath(entry), 29 | resolveRootPath('scripts/dev/bundle.min.js') 30 | ); 31 | 32 | async function main (entry, outfile) { 33 | const isWeb = mode.includes('web'); 34 | const context = await esbuild.context({ 35 | entryPoints: [ entry ], 36 | outfile, 37 | bundle: true, 38 | sourcemap: isWeb, 39 | format: isWeb ? 'esm' : 'cjs', 40 | globalName: 'Alins', 41 | platform: 'node', 42 | define: { 43 | 'process.env.NODE_ENV': '"development"', 44 | '__DEV__': 'true', 45 | '__DEBUG__': 'true', 46 | '__VERSION__': '"0.0.1-dev"' 47 | }, 48 | plugins: [ 49 | ], 50 | }); 51 | await context.watch(); 52 | console.log(`watching: ${outfile}`); 53 | } 54 | -------------------------------------------------------------------------------- /scripts/dev/data.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alinsjs/alins/80dac471deebb96cda1c4b94860deab65ad674ec/scripts/dev/data.js -------------------------------------------------------------------------------- /scripts/dev/dev-node.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-08-02 23:31:20 4 | * @Description: Coding something 5 | */ 6 | // import {parseAlins} from 'packages/compiler-node'; 7 | import {parseAlins} from 'packages/compiler-node/dist/alins-compiler-node.esm.min'; 8 | 9 | // console.log(parseAlins(` 10 | // let count = 1; 11 | 12 | // ;`)); 16 | 17 | console.log(parseAlins(` 18 | const data = useState(); 19 | data.a = 1; 20 |
{data.c}
;`)); -------------------------------------------------------------------------------- /scripts/dev/dev-web-compiler.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-08-02 23:32:10 4 | * @Description: Coding something 5 | */ 6 | 7 | import 'packages/compiler-web'; 8 | import samplesList from './samples-list'; 9 | 10 | document.write(`
11 | ${samplesList.map(name => { 12 | return `${name}`; 13 | }).join(' ')} 14 |
`); 15 | 16 | const searchParams = new URLSearchParams(location.search); 17 | 18 | const name = searchParams.get('file') || 'increment'; 19 | 20 | document.write(``); 21 | 22 | 23 | // import './samples/demo'; -------------------------------------------------------------------------------- /scripts/dev/dev-web-standalone.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-08-02 23:31:53 4 | * @Description: Coding something 5 | */ 6 | 7 | import { ref, computed, watch, Dom, join, Component } from 'packages/client-standalone'; 8 | // const { react, computed, Dom } = window.Alins; 9 | 10 | // const count = ref(1); 11 | // const countAdd1 = computed(() => count.v + 1); 12 | // Dom.button({ 13 | // $mount: document.body, 14 | // onclick: () => count.v++, 15 | // }, join`count is ${count}; countAdd1 is ${countAdd1}`); 16 | 17 | 18 | // function Counter () { 19 | // const count = ref(1); 20 | // const countAdd1 = computed(() => count.v + 1); 21 | // return Dom.button({ 22 | // $mount: document.body, 23 | // onclick: () => count.v++, 24 | // }, join`count is ${count}; countAdd1 is ${countAdd1}`); 25 | // } 26 | 27 | // Component(Counter); 28 | 29 | const count = ref(1); 30 | const countAdd1 = computed(() => count.v + 1); 31 | 32 | const button = document.createElement('button'); 33 | button.onclick = () => { count.v ++; }; 34 | document.getElementById('App').append(button); 35 | 36 | const update = () => { 37 | button.innerText = `count = ${count.v}, count+1=${countAdd1.v}`; 38 | }; 39 | update(); 40 | watch(count, update); -------------------------------------------------------------------------------- /scripts/dev/index.html: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | Alins Test 13 | 14 | 15 | 16 |
17 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /scripts/dev/samples-list.ts: -------------------------------------------------------------------------------- 1 | export default ["bench.jsx","canvas-renderer.jsx","data.js","define-renderer.jsx","define-renderer.tsx","demo.js","if-sample.tsx","increment.tsx","list.tsx","playground.jsx","rfc.html","style-reactive.jsx","template-rfc.html","todo-list.tsx","use-renderer.jsx","vjsx.tsx"]; -------------------------------------------------------------------------------- /scripts/dev/samples/canvas-renderer.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-09-10 21:16:42 4 | * @Description: Coding something 5 | */ 6 | import { useRenderer } from 'alins'; 7 | 8 | let msg = 'Hello World'; 9 | 10 | const canvas = initCanvas(); 11 | 12 | const ctx = initCanvasCtx(canvas); 13 | 14 | const root = useRenderer({ 15 | render (element) { 16 | const _parent = element.parentElement || { deep: 0 }; 17 | if (!_parent.textLeft) _parent.textLeft = 10; 18 | ctx.fillText(element.textContent, _parent.textLeft, (_parent.deep - 1) * 15 + 10); 19 | _parent.textLeft += (ctx.measureText(element.textContent).width); 20 | return el => {el.textLeft = 0;}; 21 | }, 22 | }); 23 | 24 | startCanvasRender(canvas, root); 25 | 26 | function initCanvas () { 27 | let canvas; 28 |
29 | 30 |
msg = {msg}
31 | 32 |
; 33 | return canvas; 34 | } 35 | function initCanvasCtx (canvas, size = 300) { 36 | const scale = window.devicePixelRatio; 37 | canvas.width = canvas.height = size * scale; 38 | canvas.style.width = canvas.style.height = `${size}px`; 39 | const ctx = canvas.getContext('2d'); 40 | ctx.font = `${15 * scale}px Microsoft Sans Serif`; 41 | ctx.fillStyle = '#eee'; 42 | ctx.textBaseline = 'top'; 43 | return ctx; 44 | } 45 | 46 | function startCanvasRender (canvas, root) { 47 |
48 | msg = {msg} 49 |
; 50 | function loopRender () { 51 | ctx.clearRect(0, 0, canvas.width, canvas.height); 52 | root.render(); 53 | requestAnimationFrame(loopRender); 54 | } 55 | loopRender(); 56 | } 57 | -------------------------------------------------------------------------------- /scripts/dev/samples/data.js: -------------------------------------------------------------------------------- 1 | let _ID = 1; 2 | 3 | function _random (max) { 4 | return Math.round(Math.random() * 1000) % max; 5 | } 6 | 7 | export function buildData (count = 1000) { 8 | const adjectives = [ 9 | 'pretty', 10 | 'large', 11 | 'big', 12 | 'small', 13 | 'tall', 14 | 'short', 15 | 'long', 16 | 'handsome', 17 | 'plain', 18 | 'quaint', 19 | 'clean', 20 | 'elegant', 21 | 'easy', 22 | 'angry', 23 | 'crazy', 24 | 'helpful', 25 | 'mushy', 26 | 'odd', 27 | 'unsightly', 28 | 'adorable', 29 | 'important', 30 | 'inexpensive', 31 | 'cheap', 32 | 'expensive', 33 | 'fancy' 34 | ]; 35 | const colours = [ 36 | 'red', 37 | 'yellow', 38 | 'blue', 39 | 'green', 40 | 'pink', 41 | 'brown', 42 | 'purple', 43 | 'brown', 44 | 'white', 45 | 'black', 46 | 'orange' 47 | ]; 48 | const nouns = [ 49 | 'table', 50 | 'chair', 51 | 'house', 52 | 'bbq', 53 | 'desk', 54 | 'car', 55 | 'pony', 56 | 'cookie', 57 | 'sandwich', 58 | 'burger', 59 | 'pizza', 60 | 'mouse', 61 | 'keyboard' 62 | ]; 63 | const data = []; 64 | for (let i = 0; i < count; i++) 65 | data.push({ 66 | id: _ID++, 67 | label: 68 | adjectives[_random(adjectives.length)] + 69 | ' ' + 70 | colours[_random(colours.length)] + 71 | ' ' + 72 | nouns[_random(nouns.length)] 73 | }); 74 | return data; 75 | } 76 | -------------------------------------------------------------------------------- /scripts/dev/samples/demo.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-09-06 18:17:22 4 | * @Description: Coding something 5 | */ 6 | const d = { list: [] }; 7 | 8 | d.list = createProxy(d.list); 9 | 10 | const p = createProxy(d); 11 | 12 | 13 | d.a = 1; 14 | 15 | function createProxy (d) { 16 | return new Proxy(d, { 17 | // ! 闭包 18 | get (target, property, receiver) { 19 | console.log('get', target, property, target[property]); 20 | return Reflect.get(target, property, receiver); 21 | }, 22 | // ! 闭包 23 | set (target, property, v, receiver) { 24 | console.log('set', property, target[property]); 25 | return Reflect.set(target, property, v, receiver); 26 | }, 27 | // ! 闭包 28 | deleteProperty (target, property) { 29 | console.log('deleteProperty', property, target[property]); 30 | return Reflect.deleteProperty(target, property); 31 | } 32 | }); 33 | } -------------------------------------------------------------------------------- /scripts/dev/samples/if-sample.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-08-03 14:23:44 4 | * @Description: Coding something 5 | */ 6 | let i = 0; 7 | 8 |
9 | 10 | 11 |
12 |
1111
13 | 14 | i < 2 15 | 16 | i < 1 17 | 18 | 19 | {/* */} 20 |
11
21 |
222
22 |
; 23 | 24 | 25 | -------------------------------------------------------------------------------- /scripts/dev/samples/increment.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-08-02 23:54:52 4 | * @Description: Coding something 5 | */ 6 | // import {_$$} from 'alins'; 7 | // var _$$$ = window.Alins._$$; 8 | 9 | 10 | let count = 1; 11 | 12 | ; 17 | 18 | 19 | // const a = {a: 1}; 20 | 21 | // let dom; 22 | 23 | //
; 27 | -------------------------------------------------------------------------------- /scripts/dev/samples/playground.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-10-06 23:37:14 4 | * @Description: Coding something 5 | */ 6 | 7 | // let a = 1; // @reactive 8 | // let b = false; // @reactive 9 | 10 | //
3 && !b) ? '#f44': '#4f4'}`} 12 | // > 13 | // Hello! 14 | //
15 | 16 | // a ++; 17 | // a ++; 18 | // a ++; 19 | // b = true; 20 | // // a = true; 21 | // // b = true; 22 | // // 预期绿色 23 | 24 | // const classList = ['a1']; 25 | // let a2Flag = false; 26 | // let i = 1; 27 | // function toggleClass(e){ 28 | // classList.push(`n${i++}`) 29 | // a2Flag = !a2Flag; 30 | // console.log(e.target.className) 31 | // } 32 | // ; 38 | 39 | const attrStr = 'a=va&b=vb&c=vc'; 40 | function logAttributes (e) { 41 | const attrs = e.target.attributes; 42 | for (const item of attrs) { 43 | console.log(`${item.name}=${item.value}`); 44 | } 45 | } 46 | const data = 'a'; // @reactive 47 | ; 52 | 53 | -------------------------------------------------------------------------------- /scripts/dev/samples/rfc.html: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | Document 13 | 14 | 15 |
16 |
111
17 |
18 | 111 19 | 222 20 | 333 21 |
22 |
23 | 24 | 44 | -------------------------------------------------------------------------------- /scripts/dev/samples/style-reactive.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-08-03 11:22:38 4 | * @Description: Coding something 5 | */ 6 | 7 | // let count = 1; 8 | 9 | //
{count++;}} 12 | // >click:{count}
; 13 | 14 | const style = { 15 | position: 'relative', 16 | left: '0px', 17 | top: '0px', 18 | color: '#f44', 19 | fontSize: '14px', 20 | }; 21 |
22 |
23 | 颜色: 24 | 25 |
26 |
27 | 字体大小: 28 | 29 |
30 |
31 | left: 32 | 33 |
34 |
35 | top: 36 | 37 |
38 |
显示文本
39 |
; 40 | -------------------------------------------------------------------------------- /scripts/dev/samples/template-rfc.html: -------------------------------------------------------------------------------- 1 | 6 | 24 | 25 | -------------------------------------------------------------------------------- /scripts/dev/samples/todo-list.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-08-03 00:18:07 4 | * @Description: Coding something 5 | */ 6 | 7 | // #todolist 8 | function List () { 9 | const list = [ 'todo1' ]; 10 | // eslint-disable-next-line prefer-const 11 | let value = ''; // @ 12 | return
13 |
14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 |
; 23 | } 24 | 25 | function Item ({ item, index }, children) { 26 | let done = false; 27 | return
31 | {index + 1}: {item} 32 | 33 | {children} 34 |
; 35 | } 36 | 37 | ; -------------------------------------------------------------------------------- /scripts/dev/samples/use-renderer.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-09-09 23:34:59 4 | * @Description: Coding something 5 | */ 6 | 7 | 8 | const root = window.Alins.useRenderer(); 9 | 10 | let v = 0; 11 | const v2 = v * 2; 12 | 13 |
14 | value = {v} 15 |
value * 2 = {v2}
16 |
; 17 | 18 | function loopRender () { 19 | v ++; 20 | console.clear(); 21 | root.render(); 22 | setTimeout(loopRender, 1000); 23 | } 24 | 25 | loopRender(); 26 | -------------------------------------------------------------------------------- /scripts/dev/samples/vjsx.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-06-25 19:37:29 4 | * @Description: Coding something 5 | */ 6 | 7 | function HelloWorld (): any { 8 | let msg = 'Hello World'; 9 | const show = false; 10 | if (show) { 11 | return
{msg = 'xx';}} 15 | > 16 | {msg = 'xx';}}> 17 |
; 18 | } 19 | return null; 20 | } -------------------------------------------------------------------------------- /scripts/helper/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | node_modules 3 | pnpm-lock.yaml -------------------------------------------------------------------------------- /scripts/helper/README_DEV.md: -------------------------------------------------------------------------------- 1 | 6 | ``` 7 | pnpm i 8 | npm run boot 9 | npm run build 10 | 11 | cd playground/vite 12 | pnpm i 13 | npm run dev 14 | ``` 15 | 16 | 一些规则 17 | 18 | 1. 变量定义规则 19 | 20 | ```ts 21 | const _a = 1; // 强制定义静态变量 22 | const $a = 1; // 强制定义动态变量 23 | const $$a = 1; // shallow类型的动态变量 24 | 25 | const a = 1; // @reactive // 强制定义静态变量 26 | const a = 1; // @static // 强制定义动态变量 27 | const a = 1; // @shallow // shallow 类型的动态变量 28 | ``` 29 | 30 | 2. jsx 语法糖 31 | 32 | 33 | ```ts 34 |
=>
35 |
=>
36 |
=>
37 |
=>
38 |
=>
a++}>
39 |
=>
40 |
=>
41 |
=>
42 | 43 | ``` -------------------------------------------------------------------------------- /scripts/helper/dependent-graph.json: -------------------------------------------------------------------------------- 1 | { 2 | "alins-utils": [], 3 | "alins-reactive": [ 4 | "alins-utils" 5 | ], 6 | "alins": [ 7 | "alins-utils", 8 | "alins-reactive" 9 | ], 10 | "alins-style": [ 11 | "alins-utils", 12 | "alins-reactive" 13 | ] 14 | } -------------------------------------------------------------------------------- /scripts/helper/docs/code.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alinsjs/alins/80dac471deebb96cda1c4b94860deab65ad674ec/scripts/helper/docs/code.jpg -------------------------------------------------------------------------------- /scripts/helper/docs/dev.md: -------------------------------------------------------------------------------- 1 | 6 | 7 | ## 1. [pnpm](https://zhuanlan.zhihu.com/p/373935751) 8 | 9 | 不使用 pnpm 的 workspace 10 | 11 | 21 | 22 | ## 2. [lerna](https://www.lernajs.cn/) 23 | 24 | ``` 25 | 26 | lerna add @alins/utils --scope=@alins/main 27 | 28 | lerna version 0.0.1 --yes 29 | lerna publish from-git --yes 30 | 31 | lerna version prepatch --preid alpha --no-push 32 | 33 | lerna init 34 | 35 | lerna bootstrap 36 | 37 | lerna diff [package?] 38 | 39 | lerna ls 40 | 41 | lerna changed 42 | 43 | lerna run [script] 44 | ``` 45 | 46 | http://www.febeacon.com/lerna-docs-zh-cn/routes/commands/version.html#preid 47 | 48 | 查看包之间的依赖关系 49 | 50 | yarn workspaces info 51 | 52 | ## dev 53 | 54 | npm run buildmulti 55 | 56 | npx lerna version 0.0.30 --no-git-tag-version --force-publish --yes 57 | 58 | npx lerna add xx --scope=xxx -------------------------------------------------------------------------------- /scripts/helper/docs/output.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alinsjs/alins/80dac471deebb96cda1c4b94860deab65ad674ec/scripts/helper/docs/output.jpg -------------------------------------------------------------------------------- /scripts/helper/docs/performance.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alinsjs/alins/80dac471deebb96cda1c4b94860deab65ad674ec/scripts/helper/docs/performance.jpg -------------------------------------------------------------------------------- /scripts/helper/packages-info.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "alins-utils", 4 | "version": "0.0.1", 5 | "dependencies": [] 6 | }, 7 | { 8 | "name": "alins-reactive", 9 | "version": "0.0.1", 10 | "dependencies": [ 11 | "alins-utils" 12 | ] 13 | }, 14 | { 15 | "name": "alins", 16 | "version": "0.0.1", 17 | "dependencies": [ 18 | "alins-utils", 19 | "alins-reactive" 20 | ] 21 | }, 22 | { 23 | "name": "alins-style", 24 | "version": "0.0.1", 25 | "dependencies": [ 26 | "alins-utils", 27 | "alins-reactive" 28 | ] 29 | } 30 | ] -------------------------------------------------------------------------------- /scripts/helper/qa.md: -------------------------------------------------------------------------------- 1 | 6 | ## Q: 为什么使用 $ 扩展jsx属性 7 | 8 | A: jsx原生支持的就只有 _和$,使用 _ 更奇怪,如果使用 类似 : @ 开头 就需要搞个vscode插件才可以用,不能纯粹地利用起JSX了。如果加个命名空间 类似 alins:mount 那就太冗长了,如果用普通属性比如 mount= 又会占用开发者的属性,所以比较难以取舍,权衡之下 $ 开头似乎是现阶段的最优选择了 9 | 10 | ## Q: Alins 特色、卖点 11 | 12 | A: Alins 秉持 0-API的开发理念,性能、体积、简洁度都优于vue3、react。简介一下相较于其他框架的特点或者说优点: 13 | 14 | 1. 无vdom、可以做到最最细粒度更新dom,性能极佳。(js-framework-bench跑分优于vue3和react),同时运行时体积和编译产物体积都优于两者 15 | 2. 秉持 0-API的开发理念,无任何响应式api和hooks之类的东西,同时又支持完全响应式数据、单项数据流、双向绑定。代码及其简洁,最贴近js。 16 | 3. 组件仅仅运行一次,无任何副作用。组件仅仅作为UI逻辑的组织形式,而非一个运行时需要重复渲染的模块。 -------------------------------------------------------------------------------- /scripts/helper/utils.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: tackchen 3 | * @Date: 2022-10-23 20:12:31 4 | * @Description: Coding something 5 | */ 6 | const childProcess = require('child_process'); 7 | const fs = require('fs'); 8 | const path = require('path'); 9 | 10 | function resolveRootPath (str) { 11 | return path.resolve(__dirname, `../../${str}`); 12 | } 13 | 14 | function traverseDir (path, callback) { 15 | const dirs = fs.readdirSync(checkPath(path)); 16 | dirs.map((name) => { 17 | if (name === '.DS_Store') return; 18 | callback(name); 19 | }); 20 | } 21 | 22 | function checkPath (filePath) { 23 | if (filePath[0] === '@') 24 | return resolveRootPath(filePath.substring(1)); 25 | if (filePath[0] === '#') 26 | return resolvePackagePath(filePath.substring(1)); 27 | return filePath; 28 | } 29 | 30 | function copyFile ({ 31 | src, 32 | dest = src, 33 | handler = null, 34 | json = false, 35 | }) { 36 | src = checkPath(src); 37 | dest = checkPath(dest); 38 | let content = json ? 39 | require(checkPath(src)) : 40 | readFile(src); 41 | 42 | if (handler) { 43 | content = handler(content); 44 | } 45 | json ? 46 | writeJsonIntoFile(content, dest) : 47 | writeStringIntoFile(content, dest); 48 | } 49 | 50 | function writeJsonIntoFile (package, filePath) { 51 | fs.writeFileSync(checkPath(filePath), JSON.stringify(package, null, 4), 'utf-8'); 52 | } 53 | 54 | function writeStringIntoFile (str, filePath) { 55 | fs.writeFileSync(checkPath(filePath), str, 'utf-8'); 56 | } 57 | 58 | function readFile (filePath) { 59 | return fs.readFileSync(checkPath(filePath), 'utf-8'); 60 | } 61 | 62 | async function exec (cmd, cb) { 63 | return new Promise(resolve => { 64 | const child = childProcess.exec(cmd, function (error, stdout, stderr) { 65 | if (error) { 66 | resolve({success: false, stdout, stderr}); 67 | } else { 68 | 69 | resolve({ 70 | success: true, 71 | stdout, 72 | stderr 73 | }); 74 | } 75 | }); 76 | child.stdout.on('data', data => { 77 | console.log(data); 78 | if (cb) cb(data); 79 | }); 80 | child.stderr.on('data', data => { 81 | console.log(data); 82 | }); 83 | }); 84 | } 85 | module.exports = { 86 | resolveRootPath, 87 | writeJsonIntoFile, 88 | writeStringIntoFile, 89 | traverseDir, 90 | exec, 91 | copyFile, 92 | readFile, 93 | }; 94 | -------------------------------------------------------------------------------- /scripts/info.js: -------------------------------------------------------------------------------- 1 | 2 | const {extractPackagesInfo, writeJsonIntoFile} = require('./build/utils'); 3 | 4 | const info = extractPackagesInfo(); 5 | 6 | writeJsonIntoFile(info, 'scripts/helper/packages-info.json'); 7 | 8 | console.log(info); 9 | -------------------------------------------------------------------------------- /scripts/init-learn-dep.js: -------------------------------------------------------------------------------- 1 | 2 | const execa = require('execa'); 3 | const {resolveRootPath, writeStringIntoFile} = require('./build/utils'); 4 | // const { exec } = require('./helper/tool'); 5 | 6 | const map = require(resolveRootPath('scripts/helper/dependent-graph.json')); 7 | 8 | function buildLearnAdd () { 9 | const addArr = []; 10 | for (const key in map) { 11 | const arr = map[key]; 12 | 13 | arr.forEach((dep) => { 14 | addDep(dep, key, (str) => { 15 | console.log(str); 16 | addArr.push(str); 17 | }); 18 | }); 19 | } 20 | 21 | writeStringIntoFile(addArr.join('\n'), 'scripts/lerna-add.txt'); 22 | } 23 | 24 | function addDep (dep, key, success) { 25 | execa('lerna', [ 26 | 'add', 27 | dep, 28 | `--scope=${key}`, 29 | ]).then(() => { 30 | success(`lerna add ${dep} --scope=${key}`); 31 | }); 32 | } 33 | 34 | buildLearnAdd(); 35 | 36 | -------------------------------------------------------------------------------- /scripts/init-packages-info.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: tackchen 3 | * @Date: 2022-07-06 11:55:38 4 | * @Description: 初始化package.json, 5 | * 包含 main,typings,publishConfig 6 | * 复制 remade.md, .npmignore 7 | */ 8 | 9 | 10 | const {initPackageInfo, resolveRootPath, writeJsonIntoFile} = require('./build/utils'); 11 | 12 | const isDev = process.argv[2] === 'dev'; 13 | 14 | initPackageInfo(isDev); 15 | 16 | let version = process.argv[3]; 17 | 18 | if (version) { 19 | const path = resolveRootPath('package.json'); 20 | const package = require(path); 21 | if (version[0] === 'v') version = version.substring(1); 22 | package.version = version; 23 | writeJsonIntoFile(package, path); 24 | } -------------------------------------------------------------------------------- /scripts/lerna-add.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alinsjs/alins/80dac471deebb96cda1c4b94860deab65ad674ec/scripts/lerna-add.txt -------------------------------------------------------------------------------- /scripts/playground/babel-preset/babel.config.json: -------------------------------------------------------------------------------- 1 | { 2 | // "presets": [[ 3 | // "../../packages/plugin-babel-preset/dist/babel-preset-alins.cjs.min.js", { 4 | // "ts": true 5 | // } 6 | // ]] 7 | "presets": [[ 8 | "babel-preset-alins", { 9 | "ts": true, 10 | "useImport": false 11 | } 12 | ]] 13 | } -------------------------------------------------------------------------------- /scripts/playground/babel-preset/dev/bundle.js: -------------------------------------------------------------------------------- 1 | import { _$$ } from "alins"; 2 | /* 3 | * @Author: chenzhongsheng 4 | * @Date: 2023-08-05 23:36:10 5 | * @Description: Coding something 6 | */ 7 | 8 | let count = _$$.r({ 9 | v: 1 10 | }); 11 | _$$.ce("button", { 12 | $mount: document.body, 13 | onclick: () => { 14 | count.v++; 15 | } 16 | }, "click:", count); 17 | /* 18 | 19 | { 20 | // "plugins": [ "../../packages/plugin-babel/dist/babel-plugin-alins.cjs.min.js" ], 21 | "presets": [ 22 | "@babel/preset-typescript", 23 | "@babel/preset-react" 24 | ] 25 | } 26 | 27 | 28 | */ 29 | export {}; 30 | -------------------------------------------------------------------------------- /scripts/playground/babel-preset/dev/copy-alins.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-08-08 22:35:14 4 | * @Description: Coding something 5 | */ 6 | const fs = require('fs'); 7 | const path = require('path'); 8 | 9 | fs.copyFileSync( 10 | path.resolve(__dirname, '../../../packages/client-core/dist/alins.iife.min.js'), 11 | path.resolve(__dirname, './alins.min.js') 12 | ); -------------------------------------------------------------------------------- /scripts/playground/babel-preset/dev/index.html: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | 10 | 11 | Document 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /scripts/playground/babel-preset/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "babel-preset", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "_copy_core": "node dev/copy-alins.js", 8 | "_watch": "npx babel src/alins.tsx -o dev/bundle.js -w", 9 | "_serve": "serve dev", 10 | "dev": "run-p _copy_core _watch _serve" 11 | }, 12 | "author": "", 13 | "license": "ISC", 14 | "devDependencies": { 15 | "@babel/cli": "^7.22.10", 16 | "@babel/core": "^7.22.10", 17 | "@babel/preset-env": "^7.22.10", 18 | "@babel/preset-react": "^7.22.5", 19 | "@babel/preset-typescript": "^7.22.5", 20 | "babel-preset-alins": "0.0.20-beta.5", 21 | "typescript": "^5.1.6" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /scripts/playground/babel-preset/src/alins.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-08-05 23:36:10 4 | * @Description: Coding something 5 | */ 6 | 7 | 8 | let count: number = 1; 9 | 10 | ; 14 | /* 15 | 16 | { 17 | // "plugins": [ "../../packages/plugin-babel/dist/babel-plugin-alins.cjs.min.js" ], 18 | "presets": [ 19 | "@babel/preset-typescript", 20 | "@babel/preset-react" 21 | ] 22 | } 23 | 24 | 25 | */ -------------------------------------------------------------------------------- /scripts/playground/babel/babel.config.json: -------------------------------------------------------------------------------- 1 | { 2 | // "plugins": [ ["../../packages/plugin-babel/dist/babel-plugin-alins.cjs.min.js", { 3 | // "web": true 4 | // }] ], 5 | // "plugins": ["../../packages/plugin-babel/dist/babel-plugin-alins.cjs.min.js"], 6 | "plugins": [["babel-plugin-alins", {"web": true}]], 7 | "presets": [ 8 | "@babel/preset-typescript", 9 | "@babel/preset-react" 10 | ] 11 | } -------------------------------------------------------------------------------- /scripts/playground/babel/dev/bundle.js: -------------------------------------------------------------------------------- 1 | var _$$ = window.Alins._$$; 2 | /* 3 | * @Author: chenzhongsheng 4 | * @Date: 2023-08-05 23:36:10 5 | * @Description: Coding something 6 | */ 7 | 8 | let count = _$$.r({ 9 | v: 1 10 | }); 11 | _$$.ce("button", { 12 | $mount: document.body, 13 | onclick: () => { 14 | count.v++; 15 | } 16 | }, "click:", count); 17 | /* 18 | 19 | { 20 | // "plugins": [ "../../packages/plugin-babel/dist/babel-plugin-alins.cjs.min.js" ], 21 | "presets": [ 22 | "@babel/preset-typescript", 23 | "@babel/preset-react" 24 | ] 25 | } 26 | 27 | 28 | */ 29 | -------------------------------------------------------------------------------- /scripts/playground/babel/dev/copy-alins.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-08-08 22:35:14 4 | * @Description: Coding something 5 | */ 6 | const fs = require('fs'); 7 | const path = require('path'); 8 | 9 | fs.copyFileSync( 10 | path.resolve(__dirname, '../../../packages/client-core/dist/alins.iife.min.js'), 11 | path.resolve(__dirname, './alins.min.js') 12 | ); -------------------------------------------------------------------------------- /scripts/playground/babel/dev/index.html: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | 10 | 11 | Document 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /scripts/playground/babel/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "babel", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "_copy_core": "node dev/copy-alins.js", 8 | "_watch": "npx babel src/alins.tsx -o dev/bundle.js -w", 9 | "_serve": "serve dev", 10 | "dev": "run-p _copy_core _watch _serve" 11 | }, 12 | "author": "", 13 | "license": "ISC", 14 | "devDependencies": { 15 | "@babel/cli": "^7.22.10", 16 | "@babel/core": "^7.22.10", 17 | "@babel/preset-env": "^7.22.10", 18 | "@babel/preset-react": "^7.22.5", 19 | "@babel/preset-typescript": "^7.22.5", 20 | "babel-plugin-alins": "0.0.20-beta.5", 21 | "typescript": "^5.1.6" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /scripts/playground/babel/src/alins.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-08-05 23:36:10 4 | * @Description: Coding something 5 | */ 6 | 7 | 8 | let count = 1; 9 | 10 | ; 14 | /* 15 | 16 | { 17 | // "plugins": [ "../../packages/plugin-babel/dist/babel-plugin-alins.cjs.min.js" ], 18 | "presets": [ 19 | "@babel/preset-typescript", 20 | "@babel/preset-react" 21 | ] 22 | } 23 | 24 | 25 | */ -------------------------------------------------------------------------------- /scripts/playground/compare/react/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | React non-keyed 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /scripts/playground/compare/react/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "js-framework-benchmark-non-keyed-react", 3 | "version": "1.1.1", 4 | "description": "React demo", 5 | "main": "index.js", 6 | "js-framework-benchmark": { 7 | "frameworkVersionFromPackage": "react" 8 | }, 9 | "scripts": { 10 | "build-dev": "webpack --watch", 11 | "build-prod": "webpack" 12 | }, 13 | "keywords": [ 14 | "react", 15 | "webpack" 16 | ], 17 | "author": "Stefan Krause", 18 | "license": "Apache-2.0", 19 | "homepage": "https://github.com/krausest/js-framework-benchmark", 20 | "repository": { 21 | "type": "git", 22 | "url": "https://github.com/krausest/js-framework-benchmark.git" 23 | }, 24 | "devDependencies": { 25 | "@babel/core": "7.4.5", 26 | "@babel/preset-env": "7.4.5", 27 | "@babel/preset-react": "7.0.0", 28 | "@babel/plugin-proposal-class-properties": "7.4.4", 29 | "babel-loader": "8.0.6", 30 | "terser-webpack-plugin": "1.3.0", 31 | "webpack": "4.34.0", 32 | "webpack-cli": "3.3.4" 33 | }, 34 | "dependencies": { 35 | "react": "16.8.6", 36 | "react-dom": "16.8.6" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /scripts/playground/compare/react/src/count.jsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | 4 | function Main () { 5 | const [ count, setCount ] = useState(1); 6 | function increase () { 7 | setCount(count + 1); 8 | } 9 | return ; 12 | } 13 | 14 | ReactDOM.render( 15 |
, 16 | document.body 17 | ); 18 | 19 | -------------------------------------------------------------------------------- /scripts/playground/compare/react/src/main.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-08-13 16:33:17 4 | * @Description: Coding something 5 | */ 6 | import './count.jsx'; -------------------------------------------------------------------------------- /scripts/playground/compare/react/webpack.config.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-08-13 16:33:17 4 | * @Description: Coding something 5 | */ 6 | const path = require('path'); 7 | const webpack = require('webpack'); 8 | const TerserPlugin = require('terser-webpack-plugin'); 9 | 10 | module.exports = { 11 | mode: 'production', 12 | // mode: 'development', 13 | entry: { 14 | main: path.join(__dirname, 'src', 'main.jsx'), 15 | }, 16 | output: { 17 | path: path.join(__dirname, 'dist'), 18 | filename: '[name].js' 19 | }, 20 | resolve: { 21 | extensions: ['.js', '.jsx'] 22 | }, 23 | module: { 24 | rules: [{ 25 | test: /\.jsx?$/, 26 | exclude: /node_modules/, 27 | use: [ 28 | { 29 | loader: 'babel-loader', 30 | options: { 31 | presets: ['@babel/preset-env', '@babel/preset-react'], 32 | plugins: ['@babel/plugin-proposal-class-properties'], 33 | } 34 | } 35 | ] 36 | }] 37 | }, 38 | optimization: { 39 | minimizer: [ 40 | new TerserPlugin({ 41 | terserOptions: { 42 | parse: { 43 | // we want terser to parse ecma 8 code. However, we don't want it 44 | // to apply any minfication steps that turns valid ecma 5 code 45 | // into invalid ecma 5 code. This is why the 'compress' and 'output' 46 | // sections only apply transformations that are ecma 5 safe 47 | // https://github.com/facebook/create-react-app/pull/4234 48 | ecma: 8, 49 | }, 50 | compress: { 51 | ecma: 5, 52 | warnings: false, 53 | // Disabled because of an issue with Uglify breaking seemingly valid code: 54 | // https://github.com/facebook/create-react-app/issues/2376 55 | // Pending further investigation: 56 | // https://github.com/mishoo/UglifyJS2/issues/2011 57 | comparisons: false, 58 | }, 59 | mangle: { 60 | safari10: true, 61 | }, 62 | output: { 63 | ecma: 5, 64 | comments: false, 65 | // Turned on because emoji and regex is not minified properly using default 66 | // https://github.com/facebook/create-react-app/issues/2488 67 | ascii_only: true, 68 | }, 69 | }, 70 | // Use multi-process parallel running to improve the build speed 71 | // Default number of concurrent runs: os.cpus().length - 1 72 | parallel: true, 73 | // Enable file caching 74 | cache: true, 75 | }), 76 | ] 77 | }, 78 | plugins: [ 79 | new webpack.DefinePlugin({ 80 | 'process.env': {NODE_ENV: JSON.stringify('production')} 81 | }), 82 | ], 83 | }; 84 | -------------------------------------------------------------------------------- /scripts/playground/esbuild/dev/dev.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-08-08 09:07:13 4 | * @Description: Coding something 5 | */ 6 | const esbuild = require('esbuild'); 7 | const path = require('path'); 8 | // const alins = require('../../../packages/plugin-esbuild/dist/esbuild-plugin-alins.cjs.min'); 9 | const alins = require('esbuild-plugin-alins'); 10 | 11 | main( 12 | path.resolve(__dirname, '../src/index.ts'), 13 | path.resolve(__dirname, './bundle.js') 14 | ); 15 | 16 | async function main (entry, outfile) { 17 | const context = await esbuild.context({ 18 | entryPoints: [ entry ], 19 | outfile, 20 | bundle: true, 21 | sourcemap: false, 22 | format: 'iife', 23 | plugins: [alins()], 24 | }); 25 | await context.watch(); 26 | console.log(`watching: ${outfile}`); 27 | } 28 | 29 | // console.log(esbuild.transformSync(` 30 | // import {createContext as _$$} from '../../../packages/client-core/dist/alins.esm.min' 31 | // import plugin from '../../../packages/plugin-babel/src/index'; 32 | 33 | // let count = 1; 34 | 35 | // let React: any; 36 | 37 | // ; 41 | // `, { 42 | // loader: 'tsx', 43 | // jsx: 'preserve', 44 | // })); -------------------------------------------------------------------------------- /scripts/playground/esbuild/dev/index.html: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | 10 | 11 | Document 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /scripts/playground/esbuild/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "esbuild", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "_watch": "node dev/dev.js", 8 | "_serve": "serve dev", 9 | "dev": "run-p _watch _serve" 10 | }, 11 | "keywords": [], 12 | "author": "", 13 | "license": "ISC", 14 | "devDependencies": { 15 | "esbuild": "^0.18.19", 16 | "esbuild-plugin-alins": "0.0.20-beta.5", 17 | "npm-run-all": "^4.1.5" 18 | }, 19 | "dependencies": { 20 | "alins": "0.0.20-beta.1" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /scripts/playground/esbuild/src/alins.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-08-08 09:06:19 4 | * @Description: Coding something 5 | */ 6 | 7 | let count = 1; 8 | 9 | ; -------------------------------------------------------------------------------- /scripts/playground/esbuild/src/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-08-08 09:06:15 4 | * @Description: Coding something 5 | */ 6 | import './alins'; 7 | // console.log(111) -------------------------------------------------------------------------------- /scripts/playground/rollup/dev/alins.tsx: -------------------------------------------------------------------------------- 1 | let count = 1; 2 | 3 | ; -------------------------------------------------------------------------------- /scripts/playground/rollup/dev/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Document 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /scripts/playground/rollup/dev/rollup.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-08-08 17:03:59 4 | * @Description: Coding something 5 | */ 6 | /* 7 | * @Author: chenzhongsheng 8 | * @Date: 2023-08-08 17:03:59 9 | * @Description: Coding something 10 | */ 11 | const {nodeResolve} = require('@rollup/plugin-node-resolve'); 12 | const rollup = require('rollup'); 13 | const path = require('path'); 14 | // const typescript = require('@rollup/plugin-typescript'); 15 | // const alins = require('../../../packages/plugin-rollup/dist/rollup-plugin-alins.cjs.min'); 16 | const alins = require('rollup-plugin-alins'); 17 | 18 | build(); 19 | 20 | async function build () { 21 | rollup.watch({ 22 | input: path.resolve(__dirname, './alins.tsx'), 23 | plugins: [ 24 | nodeResolve(), 25 | // typescript(), 26 | alins(), 27 | ], 28 | output: { 29 | file: path.resolve(__dirname, './bundle.js'), 30 | format: 'iife', 31 | }, 32 | }); 33 | } 34 | 35 | -------------------------------------------------------------------------------- /scripts/playground/rollup/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rollup", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "_watch": "npx node ./dev/rollup.js", 8 | "_serve": "serve dev", 9 | "dev": "run-p _watch _serve" 10 | }, 11 | "keywords": [], 12 | "author": "", 13 | "license": "ISC", 14 | "devDependencies": { 15 | "@rollup/plugin-node-resolve": "^15.1.0", 16 | "@rollup/plugin-typescript": "^11.1.2", 17 | "rollup": "^3.27.2", 18 | "rollup-plugin-alins": "0.0.20-beta.5" 19 | }, 20 | "dependencies": { 21 | "alins": "0.0.20-beta.1" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /scripts/playground/vite/index.html: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | Vite + TS 13 | 14 | 15 |
16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /scripts/playground/vite/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vite-plugin-playground", 3 | "version": "0.0.0", 4 | "scripts": { 5 | "dev": "vite", 6 | "build": "tsc && vite build", 7 | "preview": "vite preview" 8 | }, 9 | "devDependencies": { 10 | "protocol-buffers-schema": "^3.6.0", 11 | "typescript": "^4.6.4", 12 | "vite": "^3.2.3", 13 | "vite-plugin-alins": "0.0.20-beta.5" 14 | }, 15 | "type": "module", 16 | "dependencies": { 17 | "@types/node": "^18.11.18", 18 | "alins": "0.0.20-beta.1" 19 | } 20 | } -------------------------------------------------------------------------------- /scripts/playground/vite/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /scripts/playground/vite/src/alins.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-08-05 23:36:10 4 | * @Description: Coding something 5 | */ 6 | 7 | // import {createContext as _$$} from '../../../packages/client-core/dist/alins.esm.min' 8 | // (window as any)._$$ = _$$; 9 | let count = 1; 10 | 11 | ; 15 | -------------------------------------------------------------------------------- /scripts/playground/vite/src/main.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2022-11-25 10:42:14 4 | * @Description: Coding something 5 | */ 6 | 7 | import './alins'; 8 | 9 | console.log(1); -------------------------------------------------------------------------------- /scripts/playground/vite/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-08-15 09:56:14 4 | * @Description: Coding something 5 | */ 6 | // eslint-disable-next-line spaced-comment 7 | /// 8 | 9 | declare const __DEV__: boolean; 10 | declare const __DEBUG__: boolean; 11 | declare const __VERSION__: string; -------------------------------------------------------------------------------- /scripts/playground/vite/test.html: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | Vite + TS 13 | 14 | 15 |
16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /scripts/playground/vite/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "outDir": "dist", 5 | "sourceMap": false, 6 | "target": "es2016", 7 | "module": "esnext", 8 | "moduleResolution": "node", 9 | "allowJs": true, 10 | "noUnusedLocals": true, 11 | "strictNullChecks": true, 12 | "noImplicitAny": true, 13 | "noImplicitThis": true, 14 | "experimentalDecorators": true, 15 | "resolveJsonModule": true, 16 | "esModuleInterop": true, 17 | "removeComments": false, 18 | "jsx": "preserve", 19 | "lib": ["esnext", "dom"], 20 | "types": ["node"], 21 | "rootDir": ".", 22 | "noEmit": false, 23 | "paths": { 24 | } 25 | }, 26 | "include": [ 27 | "src" 28 | ], 29 | "exclude": [ 30 | "./node_modules" 31 | ] 32 | } 33 | -------------------------------------------------------------------------------- /scripts/playground/vite/vite.config.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2022-11-25 10:44:54 4 | * @Description: Coding something 5 | * @LastEditors: Please set LastEditors 6 | * @LastEditTime: 2023-08-10 00:05:08 7 | */ 8 | import {defineConfig} from 'vite'; 9 | // import alins from '../../packages/plugin-vite/dist/alins-vite-plugin.esm.min'; 10 | import alins from 'vite-plugin-alins'; 11 | 12 | export default defineConfig({ 13 | plugins: [ 14 | alins() 15 | ] 16 | }); -------------------------------------------------------------------------------- /scripts/playground/webpack/dev/index.html: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | 10 | 11 | Document 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /scripts/playground/webpack/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webpack", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "_watch": "npx webpack --watch", 8 | "_serve": "serve dev", 9 | "dev": "run-p _watch _serve", 10 | "test": "echo \"Error: no test specified\" && exit 1" 11 | }, 12 | "keywords": [], 13 | "author": "", 14 | "license": "ISC", 15 | "devDependencies": { 16 | "alins-loader": "0.0.20-beta.7", 17 | "ts-loader": "^9.4.4", 18 | "typescript": "^5.1.6", 19 | "webpack": "^5.88.2", 20 | "webpack-cli": "^5.1.4" 21 | }, 22 | "dependencies": { 23 | "alins": "0.0.20-beta.1" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /scripts/playground/webpack/src/alins.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-08-05 23:36:10 4 | * @Description: Coding something 5 | */ 6 | 7 | // console.log('111') 8 | 9 | // import {createContext as _$$} from '../../../packages/client-core/dist/alins.esm.min' 10 | // (window as any)._$$ = _$$; 11 | 12 | let count = 1; 13 | 14 | ; -------------------------------------------------------------------------------- /scripts/playground/webpack/src/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-08-07 23:43:18 4 | * @Description: Coding something 5 | */ 6 | import 'alins'; 7 | import './alins.tsx'; -------------------------------------------------------------------------------- /scripts/playground/webpack/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "outDir": "dist", 5 | "sourceMap": false, 6 | "target": "es2016", 7 | "module": "esnext", 8 | "moduleResolution": "node", 9 | "allowJs": true, 10 | // "strict": false, 11 | "noUnusedLocals": true, 12 | "strictNullChecks": true, 13 | "noImplicitAny": true, 14 | "noImplicitThis": true, 15 | "experimentalDecorators": true, 16 | "resolveJsonModule": true, 17 | "esModuleInterop": true, 18 | "removeComments": false, 19 | "jsx": "preserve", 20 | "lib": ["esnext", "dom"], 21 | "types": ["node", "alins"], 22 | "rootDir": ".", 23 | "noEmit": false, 24 | "paths": { 25 | } 26 | }, 27 | "include": [ 28 | "src" 29 | ], 30 | "exclude": [ 31 | "./node_modules" 32 | ] 33 | } 34 | -------------------------------------------------------------------------------- /scripts/playground/webpack/webpack.config.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-08-08 08:07:14 4 | * @Description: Coding something 5 | */ 6 | const path = require('path'); 7 | 8 | module.exports = { 9 | mode: 'development', 10 | entry: './src/index.ts', 11 | output: { 12 | path: path.resolve(__dirname, 'dev'), 13 | filename: 'bundle.js', 14 | }, 15 | resolve: { 16 | alias: { 17 | 'alins': path.resolve(__dirname, '../../packages/client-core/dist/alins.esm.min.js') 18 | } 19 | }, 20 | module: { 21 | rules: [{ 22 | test: /\.ts$/, 23 | use: [{loader: 'ts-loader'}] 24 | }, { 25 | test: /\.[jt]sx$/, 26 | use: [ 27 | {loader: '../../packages/plugin-webpack/dist/alins-loader.cjs.min.js'}, 28 | // {loader: 'alins-loader'}, 29 | ] 30 | }] 31 | } 32 | }; -------------------------------------------------------------------------------- /scripts/purge-cdn.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: tackchen 3 | * @Date: 2022-09-28 19:52:23 4 | * @Description: Coding something 5 | */ 6 | const https = require('https'); 7 | const {resolveRootPath, traverseDir, buildPackageName} = require('./build/utils'); 8 | 9 | 10 | function purge () { 11 | traverseDir(resolveRootPath('packages'), dir => { 12 | const name = buildPackageName(dir); 13 | https.get(`https://purge.jsdelivr.net/npm/${name}/${name}.min.js`, () => { 14 | }); 15 | if (dir === 'style') { 16 | https.get(`https://purge.jsdelivr.net/npm/${name}/alins-style.standalone.min.js`, () => { 17 | }); 18 | } 19 | }); 20 | } 21 | 22 | purge(); 23 | -------------------------------------------------------------------------------- /scripts/push-release.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: tackchen 3 | * @Date: 2022-04-06 09:14:55 4 | * @LastEditors: Please set LastEditors 5 | * @LastEditTime: 2023-08-10 10:56:49 6 | * @FilePath: /cnchar/helper/push-release.js 7 | * @Description: Coding something 8 | */ 9 | 10 | const {exec} = require('./build/utils'); 11 | 12 | async function delTag (tagName) { 13 | await exec(`git tag -d ${tagName}`); 14 | await exec(`git push origin :refs/tags/${tagName}`); 15 | } 16 | 17 | // 版本发布 del 表示需要覆盖上一个版本 一般不需要 18 | // node ./helper/push-tag.js vx.x.x 19 | // node ./helper/push-tag.js vx.x.x no-del 20 | 21 | // npm run release -- vx.x.x 22 | // npm run release -- vx.x.x no-del 23 | 24 | async function main () { 25 | const argv = process.argv.slice(2); 26 | 27 | const tagName = argv[0]; 28 | if (argv[1] !== 'no-del') { 29 | console.log(`Start delete tag ${tagName}...`); 30 | await delTag(tagName); 31 | } 32 | console.log(`Start create tag ${tagName}...`); 33 | await exec(`git tag -m "version ${tagName}" ${tagName} master`); 34 | console.log(`Start push tag ${tagName}...`); 35 | await exec('git push --tags'); 36 | console.log('Finished!'); 37 | } 38 | 39 | main(); -------------------------------------------------------------------------------- /scripts/test.js: -------------------------------------------------------------------------------- 1 | const {extractPackagesInfo} = require('./build/utils'); 2 | 3 | console.log(extractPackagesInfo()); 4 | -------------------------------------------------------------------------------- /scripts/test/bugs.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-09-25 11:08:54 4 | * @Description: Coding something 5 | */ 6 | function Comp ({ id, count, add }) { 7 | return
Div{id} Now count {count} 8 | 9 |
; 10 | } 11 | function Main () { 12 | let count = 0; 13 | const add = () => {count++; console.log(count);}; 14 | if (count % 3 == 0) { 15 | return ; 16 | } else if (count % 3 == 1) { 17 | return ; 18 | } else { 19 | return ; 20 | } 21 | } 22 |
; 23 | 24 | 25 | function Main () { 26 | let count = 0; 27 | const add = () => {count++;}; 28 | const b = ; 29 | 30 | let d1; 31 | 32 | if (count % 3 == 0) { 33 | d1 =
Div1 Now count {count}
; 34 | } else if (count % 3 == 1) { 35 | d1 =
Div2 Now count {count}
; 36 | } else { 37 | d1 =
Div3 Now count {count}
; 38 | } 39 | 40 | d1.appendChild(b); 41 | return d1; 42 | } 43 |
; -------------------------------------------------------------------------------- /scripts/test/client/cases/props.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-08-25 11:17:12 4 | * @Description: Coding something 5 | */ 6 | function normal(){ 7 | let a = 1; 8 | 9 | a++; 10 | 11 |
12 | 13 |
; 14 | 15 | function Component({a: A, b, c=1}){ 16 | return
{A}{b+1}{c}
17 | } 18 | } 19 | 20 | function spread(){ 21 | let a = {a:1,b:2}; 22 | a.a ++; 23 | 24 |
25 | 26 |
; 27 | 28 | function Component({a: A, b, c=1}){ 29 | return
{A}{b+1}{c}
30 | } 31 | } 32 | 33 | function staticSpread(){ 34 | let a = {a:1,b:2}; 35 | 36 |
37 | 38 |
; 39 | 40 | function Component({a: A, b, c=1}){ 41 | return
{A}{b+1}{c}
42 | } 43 | } 44 | 45 | function propsExtend(){ 46 | let a = 1; 47 | 48 | a++; 49 | 50 |
51 | 52 |
; 53 | 54 | function Component({a: A, b, c=1}){ 55 | return
{A}{b+1}{c}
56 | } 57 | } 58 | 59 | function props(){ 60 | let a = {a:1,b:2}; 61 | a.a = 2; 62 | 63 |
64 | 65 |
; 66 | 67 | function Component(props){ 68 | console.log(props.a); 69 | return
{props.a}{props.b+1}
70 | } 71 | } -------------------------------------------------------------------------------- /scripts/test/client/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-06-27 13:52:04 4 | * @Description: Coding something 5 | */ 6 | import {startTest} from 'easy-test-lib'; 7 | // import reactive from './cases/reactive'; 8 | // import dom from './cases/dom'; 9 | // import ifCase from './cases/if'; 10 | // import asyncCase from './cases/async'; 11 | // import switchCase from './cases/switch'; 12 | import forCase from './cases/for'; 13 | // import {react, watch} from 'packages/reactive/src'; 14 | // window.react = react; 15 | // window.watch = watch; 16 | 17 | function startTestMain () { 18 | document.body.innerText = ''; 19 | startTest({ 20 | cases: [ 21 | // ...reactive, 22 | // ...dom, 23 | // ...ifCase, 24 | // ...asyncCase, 25 | // ...switchCase, 26 | ...forCase, 27 | ], 28 | onTestComplete ({passed, results, time}) { 29 | console.log(`%c【TEST ${passed ? 'PASSED' : 'FAILED'}!(case count=${results.length})】[time=${time}]`, `color: ${passed ? 'green' : 'red'}`); 30 | // console.log(results); 31 | results.forEach(({name, index, passed, result, expect}) => { 32 | console.log(`%c【name=${name}】[${index}]${passed ? 'passed' : 'failed'}!`, `color: ${passed ? 'green' : 'red'}`); 33 | const text = ` ----result:${JSON.stringify(result)} ${!passed ? `\n ----expect:${JSON.stringify(expect)}` : ''}`; 34 | console.info(text); 35 | }); 36 | 37 | } 38 | }); 39 | } 40 | (window as any).startTestMain = startTestMain; 41 | 42 | startTestMain(); 43 | -------------------------------------------------------------------------------- /scripts/test/compiler/compiler-base.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-06-27 13:52:04 4 | * @Description: Coding something 5 | */ 6 | import {startTest} from 'easy-test-lib'; 7 | import react from './compiler-cases/react'; 8 | import jsx from './compiler-cases/jsx'; 9 | import ifCase from './compiler-cases/if'; 10 | import asyncCase from './compiler-cases/async'; 11 | import switchCase from './compiler-cases/switch'; 12 | import mapCase from './compiler-cases/map'; 13 | import test from './compiler-cases/test'; 14 | import mix from './compiler-cases/mix'; 15 | import {createTestCase} from './util'; 16 | 17 | export function startTestMain ( 18 | parse: any, 19 | log: {n:(t:string)=>void, red:(t:string)=>void, green:(t:string)=>void, log: (t:string)=>void 20 | }) { 21 | startTest({ 22 | args: {parse}, 23 | cases: createTestCase([ 24 | ...react, 25 | ...jsx, 26 | ...ifCase, 27 | ...asyncCase, 28 | ...switchCase, 29 | ...mapCase, 30 | ...mix, 31 | ...test, 32 | ]), 33 | onTestComplete ({passed, results, time}) { 34 | let failCount = 0; 35 | const logResult = () => { 36 | log[passed ? 'green' : 'red'](`【TEST ${passed ? 'PASSED' : 'FAILED'}!】[count=${results.length}; ${failCount ? `fail=${failCount};` : ''} time=${time}]`); 37 | }; 38 | logResult(); 39 | // console.log(results); 40 | results.forEach(({name, disabled, index, passed, result, expect}) => { 41 | if (passed) { 42 | if (!disabled) log.green(`【name=${name}】PASSED!`); 43 | return; 44 | } 45 | failCount ++; 46 | log[passed ? 'green' : 'red'](`【name=${name}】[${index}]${passed ? 'passed' : 'failed'}!`); 47 | // const text = ` ----result:${JSON.stringify(result)} ${!passed ? `\n ----expect:${JSON.stringify(expect)}` : ''}`; 48 | console.log('-----result:'); 49 | console.log(result); 50 | if (!passed) { 51 | console.log('-----expect:'); 52 | console.log(expect); 53 | } 54 | }); 55 | logResult(); 56 | } 57 | }); 58 | } -------------------------------------------------------------------------------- /scripts/test/compiler/compiler-cases/async.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-07-01 01:15:31 4 | * @Description: Coding something 5 | */ 6 | import {ICodeMap} from '../util'; 7 | // import { parseAlins } from 'src/node-parser'; 8 | 9 | // input: 'import aa from "aa"; var a=1;export let b=a+1; a=2;var s = `${a}${a+1}`;var d=
{a}{a+1}
', 10 | 11 | export default [ 12 | { 13 | name: 'async base', 14 | disabled: false, 15 | input: ` 16 | async function fn() { 17 | let b = await aa(); 18 | b = await aa(); 19 | return
{b}
; 20 | } 21 | `, 22 | output: ` 23 | async function fn() { 24 | let b = _$$.r({ 25 | v: await aa() 26 | }); 27 | b.v = await aa(); 28 | return _$$.ce("div", null, b); 29 | } 30 | ` 31 | }, 32 | { 33 | name: 'async if', 34 | disabled: false, 35 | input: ` 36 | async function fn() { 37 | let b = await aa(); 38 | if(b) { 39 | let b = await aa(); 40 | return 1 41 | } 42 | b = await aa(); 43 | return
{b}
; 44 | } 45 | `, 46 | output: ` 47 | const _$ = _$$(); 48 | async function fn() { 49 | let b = _$$.r({ 50 | v: await aa() 51 | }); 52 | return _$.if(() => b.v, async () => { 53 | let b = await aa(); 54 | return 1; 55 | }).end(_$$.mnr(async () => { 56 | b.v = await aa(); 57 | return _$$.ce("div", null, b); 58 | })); 59 | } 60 | ` 61 | } 62 | ] as ICodeMap[]; 63 | -------------------------------------------------------------------------------- /scripts/test/compiler/compiler-cases/props.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-07-01 01:15:31 4 | * @Description: Coding something 5 | */ 6 | import {ICodeMap} from '../util'; 7 | // import { parseAlins } from 'src/node-parser'; 8 | 9 | // input: 'import aa from "aa"; var a=1;export let b=a+1; a=2;var s = `${a}${a+1}`;var d=
{a}{a+1}
', 10 | 11 | export default [ 12 | { 13 | name: 'props', 14 | disabled: false, 15 | input: ` 16 | `, 17 | output: ` 18 | ` 19 | }, 20 | 21 | ] as ICodeMap[]; 22 | -------------------------------------------------------------------------------- /scripts/test/compiler/compiler-cases/test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-07-01 01:15:31 4 | * @Description: Coding something 5 | */ 6 | import {ICodeMap} from '../util'; 7 | // import { parseAlins } from 'src/node-parser'; 8 | 9 | // input: 'import aa from "aa"; var a=1;export let b=a+1; a=2;var s = `${a}${a+1}`;var d=
{a}{a+1}
', 10 | 11 | export default [ 12 | { 13 | name: 'test', 14 | disabled: false, 15 | input: ` 16 | var a = 1; 17 | var list = [1,2,3,4] 18 | 19 | document.body.appendChild( 20 | <> 21 | 27 | { 28 | list.map((v, i)=>{ 29 | return
{i}:{v}
30 | }) 31 | } 32 | 33 | ); 34 | `, 35 | output: ` 36 | var a = _$$.r({ 37 | v: 1 38 | }); 39 | var list = _$$.r({ 40 | v: [1, 2, 3, 4] 41 | }); 42 | document.body.appendChild(_$$.ce("", null, _$$.ce("button", { 43 | onclick: () => { 44 | a.v++; 45 | list.v.push(a.v); 46 | } 47 | }, a), list.v.map((v, i) => { 48 | return _$$.ce("div", null, i, ":", v); 49 | }, true, "v", "i"))); 50 | ` 51 | }, 52 | ] as ICodeMap[]; 53 | -------------------------------------------------------------------------------- /scripts/test/compiler/node.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-07-13 11:08:13 4 | * @Description: Coding something 5 | */ 6 | /* 7 | * @Author: chenzhongsheng 8 | * @Date: 2023-07-13 08:53:45 9 | * @Description: Coding something 10 | */ 11 | import {parseAlins} from 'packages/compiler-node'; 12 | import {startTestMain} from './compiler-base'; 13 | import chalk from 'chalk'; 14 | 15 | const _ = console.log; 16 | const isUd = function (o: any) {return typeof o === 'undefined';}; 17 | 18 | const log = { 19 | n: function (txt: string) { 20 | if (isUd(txt)) { 21 | _(); 22 | return; 23 | } 24 | _(txt); 25 | }, 26 | green: function (txt: string) { 27 | _(chalk.green(txt)); 28 | }, 29 | red: function (txt: string) { 30 | _(chalk.red(txt)); 31 | }, 32 | log: function (txt: string) { 33 | _(txt); 34 | }, 35 | }; 36 | 37 | startTestMain(parseAlins, log); 38 | 39 | // console.log(parseAlins('
')); 40 | 41 | -------------------------------------------------------------------------------- /scripts/test/compiler/util.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-08-03 00:08:16 4 | * @Description: Coding something 5 | */ 6 | import {ITestConfigItem} from 'easy-test-lib'; 7 | 8 | export interface ICodeMap { 9 | name?: string; 10 | disabled?: boolean; 11 | input: string; 12 | output: string; 13 | } 14 | 15 | export function createTestCase (codeMap: ICodeMap[]) { 16 | const isWeb = 'object' === typeof window && !!window.navigator; 17 | const head = isWeb ? 'var _$$ = window.Alins._$$;\n' : 'import { _$$ } from "alins";\n'; 18 | return codeMap.map((item, index) => ({ 19 | name: item.name || `test-compile-react-${index}`, 20 | disabled: item.disabled ?? false, 21 | test ({parse}: any) { 22 | return parse(item.input || '').replace('"use strict";', '').trim(); 23 | }, 24 | expect: `${head}${item.output.trim()}`, 25 | })) as ITestConfigItem[]; 26 | } -------------------------------------------------------------------------------- /scripts/test/compiler/web.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-07-13 08:53:45 4 | * @Description: Coding something 5 | */ 6 | import {parseWebAlins} from 'packages/compiler-web'; 7 | import {startTestMain} from './compiler-base'; 8 | 9 | const _ = console.log; 10 | const isUd = function (o: any) {return typeof o === 'undefined';}; 11 | 12 | const log = { 13 | n: function (txt: string) { 14 | if (isUd(txt)) { 15 | _(); 16 | return; 17 | } 18 | _(txt); 19 | }, 20 | green: function (txt: string) { 21 | _(`%c${txt}`, 'color: green'); 22 | }, 23 | red: function (txt: string) { 24 | _(`%c${txt}`, 'color: red'); 25 | }, 26 | log: function (txt: string) { 27 | _(txt); 28 | }, 29 | }; 30 | 31 | // console.log(parseWebAlins, startTestMain); 32 | 33 | startTestMain(parseWebAlins, log); -------------------------------------------------------------------------------- /scripts/test/test-util.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-07-07 22:36:11 4 | * @Description: Coding something 5 | */ 6 | 7 | export async function mockFetch (s: T) { 8 | await delay(100); 9 | return s; 10 | } 11 | export function delay (time = 500) { 12 | return new Promise(resolve => { 13 | setTimeout(() => { 14 | resolve(1); 15 | }, time); 16 | }); 17 | } -------------------------------------------------------------------------------- /scripts/v1-parser.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenzhongsheng 3 | * @Date: 2023-06-25 20:13:00 4 | * @Description: Coding something 5 | */ 6 | const swc = require('@swc/core'); 7 | 8 | const fs = require('fs'); 9 | 10 | const code = ` 11 | function HelloWorld () { 12 | let msg = 'Hello World'; 13 | const show = false; 14 | if (show) { 15 | return div({ 16 | html: '', 17 | text: '', 18 | style: {}, 19 | class: \`\${show ? 'aa' : msg}\`, 20 | attr: {aa: 11}, 21 | click: () => {msg = 'xx';}, 22 | children: [ 23 | span({click: () => {msg = 'xx';}}, [ 24 | div({}) 25 | ]) 26 | ] 27 | }); 28 | } 29 | return null; 30 | }`; 31 | 32 | swc 33 | .parse(code, { 34 | syntax: 'ecmascript', // "ecmascript" | "typescript" 35 | comments: false, 36 | script: true, 37 | 38 | // Defaults to es3 39 | target: 'es3', 40 | 41 | // Input source code are treated as module by default 42 | isModule: false, 43 | }) 44 | .then((module) => { 45 | module.type; // file type 46 | module.body; // AST 47 | console.log(module.type, module.body); 48 | 49 | fs.writeFileSync('a.json', JSON.stringify(module), 'utf-8'); 50 | }); 51 | 52 | swc.transform(code, { 53 | 54 | '' 55 | }) -------------------------------------------------------------------------------- /scripts/version.md: -------------------------------------------------------------------------------- 1 | 8 | 9 | ## v0.0.19 doing 10 | 11 | 1. 支持for控制器不传callback 12 | 2. 导出 IReactWrap, IReactObject 与 IReactItem 不导出 或使用 _ 标注 13 | 14 | ## v0.0.18 15 | 16 | 1. 修复text中的空格问题 17 | 2. 零宽断言兼容处理 18 | 3. 重构domInfo逻辑 彻底修复node reaction-node dom builder的显示顺序问题 19 | 20 | ## v0.0.16 - v0.0.17 21 | 22 | 1. fix: 数组length问题 23 | 2. css样式支持多个一起写 css('.aa')(['.a1,.a2', style.color(111)]) 24 | 3. 支持 text builder 数字 和文本 顺序一致 div(span('web-os'), ' :22.cc:44 ', text(' made by '), '33', text('11')).mount(); 25 | 26 | ## v0.0.15 27 | 28 | fix: wordWrap break-all [done] 29 | fix: wordBreak break-word [done] 30 | 移除多余的log [feat] 31 | fix: 删除多余的mergereact [fix] 32 | feat: 原子样式增加 get方法,支持 获取属性值 ._reslut.color ... [done] 33 | feat: 控制器支持 computed 34 | feat: 支持对数组length 进行动态监听 35 | 36 | ## v0.0.13-v0.0.14 37 | 38 | 1. feat: style: supporteAdoptedStyle 支持配置打开或者关闭 useAdoptedStyle [done] 39 | 2. feat: css函数支持传入 json,且有支持提示 [done] 40 | 3. feat: style枚举属性 提示 [done] 41 | 4. fix: 原子属性缺少 minWidth minHeight [done] 42 | 5. fix: 补全ts声明 43 | 44 | 45 | ## v0.0.12 46 | 47 | 1. feat: 修复 组件 + show同时使用时初始化渲染问题 [done] 48 | 49 | ## v0.0.11 50 | 51 | 1. feat: comp 科里化 comp(Hello)() [done] 52 | 2. feat: click.stop 简化写法 [done] 53 | 3. feat: atomStyle 新增 join 方法 [done] 54 | 4. feat: 声明提示优化 TType & {[prop: string]: any;} [done] 55 | 5. feat: 通过重载支持string和枚举共存 [done] 56 | 6. feat: model 支持通过识别 type=number来增加number修饰符 [done] 57 | 7. fix: 文本中 . [] # / 不显示 : / [] 字符串冲突问题 [done] 使用text方法 58 | 8. fix: alins-utils ts 声明文件问题 [done] 59 | 9. fix: subscribe return value; [done] 60 | 10. fix: 事件声明 不起作用 [done] 61 | 11. del: splitTwoPart 函数重复 [done] 62 | 12. fix: 修复兼容属性重复补全问题 [done] 63 | 13. fix: style 多数据绑定中绑定报错的问题 [done] 64 | 14. fix: 修复对象类型和computed组合使用时 闭包对象数值不更新问题 [done] 65 | 66 | ## 0.0.10 67 | 68 | 1. 修复ts声明文件引用错误问题 69 | 70 | ## 0.0.9 71 | 72 | 1. input builder & modelReturn 支持 mount 73 | 2. feat: dom 支持直接使用 react数据作为textContent 74 | 3. fix: comp和dom builder使用函数作为参数 75 | 4. fix: style 多数据绑定中绑定报错的问题 76 | 77 | ## 0.0.8 78 | 79 | 1. fix: div('.class', 'text').mount(); 文本节点不渲染 的bug 80 | 2. feat: mount可以挂载到 其他节点或者 comp上 81 | 3. feat: 事件中访问 this dom 82 | 4. fix: On 函数设计有误 83 | 5. fix: 对于arg传入函数出现的bug fix 84 | 6. fix: object reactive subscrube 85 | 7. fix: 数组重新赋值之后属性丢失,下标引用绑定丢失 86 | 87 | ## 0.0.7 88 | 89 | 1. 增加controller mount功能 90 | 2. 增加html builder 91 | 3. 修复if bug 92 | 4. for callback返回支持单个builder 93 | 94 | ## 0.0.6 95 | 96 | 1. 导出 IReactObject IComputedItem 97 | 2. fix for循环bug 98 | 3. fix 对象、数组直接赋值bug 99 | 4. 增加一级对象直接赋值功能 100 | 101 | ## 0.0.1-0.0.5 102 | 103 | 1. 初始版本 -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "outDir": "dist", 5 | "sourceMap": false, 6 | "target": "es2016", 7 | "module": "esnext", 8 | "moduleResolution": "node", 9 | "allowJs": true, 10 | "noUnusedLocals": true, 11 | "strictNullChecks": true, 12 | // "noImplicitAny": true, 13 | "noImplicitThis": true, 14 | "experimentalDecorators": true, 15 | "resolveJsonModule": true, 16 | "esModuleInterop": true, 17 | "removeComments": false, 18 | "jsx": "preserve", 19 | "lib": ["esnext", "dom"], 20 | "types": ["node"], 21 | "rootDir": ".", 22 | "noEmit": false, 23 | "paths": {}, 24 | "noImplicitAny": false, 25 | }, 26 | "include": [ 27 | "packages/*/src/**/*", 28 | "packages/*/v1/**/*", 29 | ".eslintrc.js", 30 | "babel.config.js", 31 | "scripts/**/*", 32 | "src/**/*", 33 | "global.d.ts", 34 | "playground/**/*.js", 35 | "playground/**/*.jsx", 36 | "playground/**/*.ts", 37 | "packages/plugin-eslint/*.js", 38 | ".eslintrc.js" 39 | // "**/*.ts" 40 | ], 41 | "exclude": [ 42 | "./node_modules" 43 | ] 44 | } --------------------------------------------------------------------------------