├── .commitlintrc.js ├── .eslintignore ├── .eslintrc ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── feature_request.md │ └── question.md ├── PULL_REQUEST_TEMPLATE.md └── stale.yml ├── .gitignore ├── .yarnrc ├── Design.md ├── LICENSE ├── README.md ├── circle.yml ├── examples ├── child1 │ ├── package.json │ ├── pages.config.js │ └── src │ │ └── pages │ │ ├── a.vue │ │ └── b.vue ├── child2 │ ├── package.json │ ├── pages.config.js │ └── src │ │ └── pages │ │ ├── c.vue │ │ └── d.vue ├── host │ ├── package.json │ ├── pages.config.js │ └── src │ │ ├── app.js │ │ └── public │ │ └── _redirects ├── next │ ├── .browserslistrc │ ├── CHANGELOG.md │ ├── package.json │ ├── pages.config.js │ ├── plugins │ │ ├── plugin-rem.js │ │ └── runtime.js │ └── src │ │ ├── app.vue │ │ ├── components │ │ ├── Hello.vue │ │ └── Home.vue │ │ ├── create-app.js │ │ ├── entry-client.js │ │ ├── entry-server.js │ │ ├── index.js │ │ ├── index.scss │ │ └── router.js ├── now2 │ ├── package.json │ ├── pages.config.js │ └── src │ │ ├── app.js │ │ ├── pages │ │ ├── demo.vue │ │ ├── demo2.vue │ │ ├── demo3.vue │ │ ├── home.vue │ │ └── markdown.md │ │ └── public │ │ └── nut-logo.png ├── simple │ ├── .eslintrc │ ├── CHANGELOG.md │ ├── babel.config.js │ ├── config │ │ ├── config.default.js │ │ ├── config.dev.js │ │ ├── config.prod.js │ │ ├── plugin.default.js │ │ ├── plugin.dev.js │ │ └── plugin.prod.js │ ├── package.json │ ├── pages.config.js │ ├── plugins │ │ ├── layout-test │ │ │ ├── index.module.less │ │ │ └── pages.browser.js │ │ ├── login │ │ │ ├── package.json │ │ │ └── pages.browser.js │ │ ├── notfound │ │ │ ├── pages.browser.js │ │ │ └── pages │ │ │ │ └── index.js │ │ └── test │ │ │ └── pages.browser.js │ ├── src │ │ ├── app.ts │ │ ├── components │ │ │ ├── demo.vue │ │ │ └── object.js │ │ └── pages │ │ │ ├── documents │ │ │ ├── demo.vue.md │ │ │ ├── index.md │ │ │ └── reference.md │ │ │ └── home │ │ │ ├── components │ │ │ ├── style.css │ │ │ └── style.js │ │ │ ├── demo │ │ │ └── _id.js │ │ │ ├── home.js │ │ │ ├── home.module.scss │ │ │ ├── index.vue │ │ │ ├── react.jsx │ │ │ ├── regular.js │ │ │ ├── regular.styl │ │ │ ├── typescript.ts │ │ │ └── vue.js │ ├── tsconfig.json │ └── tslint.json └── vue │ ├── CHANGELOG.md │ ├── package.json │ ├── pages.config.js │ └── src │ ├── app.js │ └── pages │ ├── hello.vue │ └── home.vue ├── lerna.json ├── media ├── default-ocean.jpg ├── default-sakura.jpg ├── hmr.gif ├── logo.png ├── markdown-theme-hmr.gif ├── now.jpg ├── route-match.jpg ├── saber-ocean.jpg ├── saber-sakura.jpg ├── social-media-preview.png └── system-events.jpg ├── other-packages ├── webpack-mini-css-extract │ ├── CHANGELOG.md │ ├── lib │ │ ├── hmr │ │ │ └── hotModuleReplacement.js │ │ ├── index.js │ │ ├── loader.js │ │ └── options.json │ └── package.json └── webpack-virtual-modules │ ├── CHANGELOG.md │ ├── lib │ ├── index.js │ └── virtual-stats.js │ └── package.json ├── package.json ├── packages ├── babel-preset │ ├── CHANGELOG.md │ ├── lib │ │ └── index.js │ └── package.json ├── cli-pages │ ├── CHANGELOG.md │ ├── lib │ │ └── index.js │ └── package.json ├── cli │ ├── CHANGELOG.md │ ├── bin │ │ └── index.js │ └── package.json ├── core │ ├── CHANGELOG.md │ ├── lib │ │ ├── cli.js │ │ ├── driver.js │ │ ├── index.js │ │ └── startup.js │ └── package.json ├── dev-utils │ ├── CHANGELOG.md │ ├── lib │ │ ├── config.js │ │ ├── index.js │ │ ├── local-require.js │ │ ├── logger.js │ │ ├── open-browser.js │ │ ├── open-chrome.applescript │ │ └── utils.js │ └── package.json ├── driver-pages │ ├── .gitignore │ ├── CHANGELOG.md │ ├── lib │ │ ├── driver.js │ │ ├── get-pages.js │ │ ├── index.js │ │ ├── runtime │ │ │ ├── context.js │ │ │ ├── entry.js │ │ │ ├── events.js │ │ │ ├── expose-use.js │ │ │ └── fake-runtime.js │ │ └── webpack │ │ │ ├── base.js │ │ │ ├── css.js │ │ │ ├── dev.js │ │ │ ├── index.js │ │ │ ├── prod.js │ │ │ ├── template.ejs │ │ │ └── tsconfig.json │ └── package.json ├── driver-webpack │ ├── CHANGELOG.md │ ├── lib │ │ ├── index.js │ │ ├── schema.js │ │ └── webpack │ │ │ ├── analyze.js │ │ │ ├── babel.js │ │ │ ├── babel │ │ │ ├── loader.js │ │ │ └── preset.js │ │ │ ├── cache.js │ │ │ ├── clean.js │ │ │ ├── copy.js │ │ │ ├── css.js │ │ │ ├── define.js │ │ │ ├── dev-server.js │ │ │ ├── devtool.js │ │ │ ├── dll.js │ │ │ ├── entry.js │ │ │ ├── error-overlay.js │ │ │ ├── error │ │ │ └── transformer-module-not-found.js │ │ │ ├── eslint.js │ │ │ ├── fast.js │ │ │ ├── filename.js │ │ │ ├── font.js │ │ │ ├── friendly-error.js │ │ │ ├── hot.js │ │ │ ├── html.js │ │ │ ├── index.js │ │ │ ├── media.js │ │ │ ├── minimize.js │ │ │ ├── minimizer.js │ │ │ ├── missing-node-modules.js │ │ │ ├── mode.js │ │ │ ├── outdir.js │ │ │ ├── overlay │ │ │ ├── client.js │ │ │ ├── error-overlay-middleware.js │ │ │ ├── format-webpack-messages.js │ │ │ ├── launch-editor-endpoint.js │ │ │ └── launch-editor.js │ │ │ ├── performance.js │ │ │ ├── plugins │ │ │ ├── FriendlyErrorPlugin.js │ │ │ ├── HtmlCheerioPlugin.js │ │ │ ├── InlineChunkHtmlPlugin.js │ │ │ └── WatchMissingNodeModulesPlugin.js │ │ │ ├── progress.js │ │ │ ├── public-path.js │ │ │ ├── resolve.js │ │ │ ├── shared │ │ │ ├── apply-css-rule.js │ │ │ ├── create-include.js │ │ │ ├── get-cache-config.js │ │ │ ├── local-join.js │ │ │ ├── local-require.js │ │ │ ├── local-resolve.js │ │ │ ├── parallel.js │ │ │ └── resolve.js │ │ │ ├── template.ejs │ │ │ ├── typescript.js │ │ │ └── vue.js │ ├── package.json │ └── plugins │ │ ├── clear-console.js │ │ ├── memory-usage.js │ │ ├── raw-html.js │ │ └── server-info.js ├── musubi │ ├── CHANGELOG.md │ ├── lib │ │ ├── index.js │ │ ├── musubi.js │ │ └── utils.js │ └── package.json ├── presets-alpha │ ├── CHANGELOG.md │ ├── lib │ │ └── index.js │ └── package.json └── webpack │ ├── CHANGELOG.md │ ├── lib │ ├── build.js │ ├── chain.js │ ├── helpers.js │ ├── hot.js │ ├── index.js │ └── serve.js │ └── package.json ├── plugins ├── modern-build │ ├── CHANGELOG.md │ ├── lib │ │ ├── index.js │ │ └── plugin.js │ └── package.json ├── pages │ ├── layout-kaola │ │ ├── CHANGELOG.md │ │ ├── lib │ │ │ ├── index.js │ │ │ ├── index.module.less │ │ │ └── runtime.js │ │ └── package.json │ ├── layout-now │ │ ├── CHANGELOG.md │ │ ├── lib │ │ │ ├── docsearch.less │ │ │ ├── headroom.module.less │ │ │ ├── index.js │ │ │ ├── index.module.less │ │ │ ├── nprogress.css │ │ │ └── runtime.js │ │ └── package.json │ ├── layout-saber │ │ ├── CHANGELOG.md │ │ ├── lib │ │ │ ├── index.js │ │ │ ├── index.module.less │ │ │ └── runtime.js │ │ └── package.json │ ├── layout-side │ │ ├── CHANGELOG.md │ │ ├── lib │ │ │ ├── index.js │ │ │ ├── index.module.less │ │ │ ├── runtime.js │ │ │ └── tippy.js │ │ └── package.json │ ├── materials │ │ ├── CHANGELOG.md │ │ ├── lib │ │ │ ├── index.js │ │ │ └── runtime │ │ │ │ ├── index.js │ │ │ │ ├── index.module.less │ │ │ │ ├── materials-market.vue │ │ │ │ └── var.less │ │ └── package.json │ ├── microfrontends │ │ ├── CHANGELOG.md │ │ ├── files │ │ │ ├── context │ │ │ │ └── api.js │ │ │ ├── core │ │ │ │ ├── homepage.js │ │ │ │ ├── layout.js │ │ │ │ ├── nico.js │ │ │ │ ├── page.js │ │ │ │ ├── quicklink.js │ │ │ │ └── router.js │ │ │ ├── css │ │ │ │ ├── markdown.less │ │ │ │ ├── override.less │ │ │ │ └── reset.less │ │ │ ├── entries │ │ │ │ ├── child.js │ │ │ │ └── default-runtime.js │ │ │ ├── fonts │ │ │ │ ├── demo.css │ │ │ │ ├── demo_index.html │ │ │ │ ├── iconfont.css │ │ │ │ ├── iconfont.eot │ │ │ │ ├── iconfont.js │ │ │ │ ├── iconfont.svg │ │ │ │ ├── iconfont.ttf │ │ │ │ ├── iconfont.woff │ │ │ │ └── iconfont.woff2 │ │ │ ├── modules │ │ │ │ └── layout-none.js │ │ │ ├── steps │ │ │ │ ├── apply-compose.js │ │ │ │ ├── apply-modules.js │ │ │ │ └── setup-nico.js │ │ │ └── utils │ │ │ │ ├── add-require-ensure.js │ │ │ │ ├── dynamic-build.js │ │ │ │ ├── dynamic-import-fixture.js │ │ │ │ ├── get-first-route.js │ │ │ │ ├── logger.js │ │ │ │ ├── normalize-route.js │ │ │ │ └── switch-theme.js │ │ ├── lib │ │ │ ├── generate-modules.js │ │ │ ├── index.js │ │ │ ├── loader │ │ │ │ ├── mdx-arrtibutes.js │ │ │ │ ├── mount-markdown.js │ │ │ │ ├── mount-react.js │ │ │ │ ├── mount-vue.js │ │ │ │ └── nutify │ │ │ │ │ ├── markdown.js │ │ │ │ │ ├── react.js │ │ │ │ │ └── vue.js │ │ │ ├── markdown │ │ │ │ └── themes │ │ │ │ │ └── prism-dracula.css │ │ │ ├── modules │ │ │ │ └── command-palette │ │ │ │ │ ├── App.vue │ │ │ │ │ ├── index.js │ │ │ │ │ ├── logo.png │ │ │ │ │ ├── toast.css │ │ │ │ │ └── toast.js │ │ │ ├── server.js │ │ │ ├── utils.js │ │ │ ├── utils │ │ │ │ ├── dirs.js │ │ │ │ ├── marked.js │ │ │ │ └── path-utils.js │ │ │ └── webpack │ │ │ │ ├── favicon.ico │ │ │ │ ├── favicon.png │ │ │ │ ├── get-babel-options.js │ │ │ │ ├── index.js │ │ │ │ ├── mdx │ │ │ │ ├── provider.js │ │ │ │ ├── tag.js │ │ │ │ ├── vue-jsx-compiler.js │ │ │ │ └── vue-loader.js │ │ │ │ └── template.ejs │ │ └── package.json │ └── runtime-vue │ │ ├── CHANGELOG.md │ │ ├── files │ │ ├── App.vue │ │ ├── app.js │ │ ├── entry-client.js │ │ ├── entry-server.js │ │ └── router.js │ │ ├── lib │ │ └── index.js │ │ └── package.json └── vue-ssr │ ├── CHANGELOG.md │ ├── lib │ ├── index.js │ └── remove-magic-html.js │ └── package.json ├── renovate.json ├── scripts └── dependency-check.js ├── templates └── pages │ ├── index.js │ ├── package.json │ ├── saofile.js │ └── template │ ├── .gitignore │ ├── package.json │ ├── pages.config.js │ └── src │ ├── app.js │ ├── pages │ ├── demo.vue │ ├── home.vue │ └── markdown.md │ └── public │ └── nut-logo.png ├── website ├── .gitignore ├── CHANGELOG.md ├── package.json ├── pages.config.js ├── plugins │ └── now-custom │ │ ├── index.js │ │ ├── now-custom-layout.vue │ │ └── runtime.js ├── search.config.js └── src │ ├── app.js │ ├── css │ └── index.less │ ├── index.ejs │ ├── pages │ ├── docs │ │ ├── api.md │ │ ├── cli.md │ │ ├── config.md │ │ └── router.md │ ├── guide │ │ ├── css-modules.vue.md │ │ ├── css-preprocessor.vue.md │ │ ├── experience.md │ │ ├── icon.vue.md │ │ ├── installation.md │ │ ├── introduction.md │ │ ├── layout.vue.md │ │ ├── markdown.vue.md │ │ ├── microfrontends.vue.md │ │ ├── plugin.md │ │ ├── public.vue.md │ │ ├── quicklink.vue.md │ │ └── theme.vue.md │ └── home.vue │ └── public │ ├── CNAME │ ├── _redirects │ ├── logo.png │ ├── no-quicklink.gif │ ├── open-in-gitpod.svg │ ├── quicklink.gif │ ├── social-media-preview-750.png │ ├── social-media-preview.png │ ├── terminal.png │ ├── website-screenshot-nut.jpg │ └── website-screenshot-todomvc.jpg └── yarn.lock /.commitlintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: [ '@commitlint/config-conventional' ], 3 | rules: { 4 | 'type-enum': [ 5 | 2, 6 | 'always', 7 | [ 8 | 'build', 9 | 'chore', 10 | 'ci', 11 | 'docs', 12 | 'feat', 13 | 'fix', 14 | 'perf', 15 | 'refactor', 16 | 'revert', 17 | 'style', 18 | 'test', 19 | 'release', 20 | 'dependency', 21 | 'breaking', 22 | ] 23 | ], 24 | 'header-max-length': [ 2, 'always', 120 ] 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | iconfont.js 3 | templates/pages/template 4 | packages/webpack-mini-css-extract 5 | packages/dev-utils/lib/open-browser.js 6 | packages/driver-webpack/lib/webpack/plugins/InlineChunkHtmlPlugin.js 7 | packages/driver-webpack/lib/webpack/plugins/WatchMissingNodeModulesPlugin.js 8 | packages/driver-webpack/lib/webpack/overlay 9 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "mo/esnext", 3 | "parser": "babel-eslint", 4 | "parserOptions": { 5 | "allowImportExportEverywhere": true 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "🐞 Bug report" 3 | about: Something is not working 4 | --- 5 | 6 | ## Bug report 7 | 8 | #### Version 9 | 10 | #### Steps to reproduce 11 | 12 | 13 | 14 | #### What is expected? 15 | 16 | #### What is actually happening? 17 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "⭐ Feature request" 3 | about: Suggest an idea 4 | --- 5 | 6 | ## Feature request 7 | 8 | #### What problem are you trying to solve? 9 | 10 | #### Describe the feature 11 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/question.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "❓ Question" 3 | about: Something is unclear 4 | --- 5 | 6 | ## Question 7 | 8 | #### What would you like to ask or discuss? 9 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | **What kind of change does this PR introduce?** (check at least one) 2 | 3 | - [ ] Bugfix 4 | - [ ] Feature 5 | - [ ] Code style update 6 | - [ ] Refactor 7 | - [ ] Docs 8 | - [ ] Build-related changes 9 | - [ ] Other, please describe: 10 | 11 | **Does this PR introduce a breaking change?** (check one) 12 | 13 | - [ ] Yes 14 | - [ ] No 15 | 16 | If yes, please describe the impact and migration path for existing applications: 17 | -------------------------------------------------------------------------------- /.github/stale.yml: -------------------------------------------------------------------------------- 1 | # Number of days of inactivity before an issue becomes stale 2 | daysUntilStale: 180 3 | # Number of days of inactivity before a stale issue is closed 4 | daysUntilClose: 15 5 | # Issues with these labels will never be considered stale 6 | exemptLabels: 7 | - "Type: Bug" 8 | only: issues 9 | # Label to use when marking an issue as stale 10 | staleLabel: stale? 11 | # Comment to post when marking an issue as stale. Set to `false` to disable 12 | markComment: > 13 | This issue has been automatically marked as stale because it has not had 14 | recent activity. It will be closed if no further activity occurs. Thank you 15 | for your contributions. 16 | # Comment to post when closing a stale issue. Set to `false` to disable 17 | closeComment: > 18 | This issue has been automatically closed due to inactivity. 19 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | /server 3 | /website/demo 4 | /website/materials-url.js 5 | /packages/**/README.md 6 | .DS_Store 7 | package-lock.json 8 | 9 | # Logs 10 | logs 11 | *.log 12 | npm-debug.log* 13 | yarn-debug.log* 14 | yarn-error.log* 15 | 16 | # Runtime data 17 | pids 18 | *.pid 19 | *.seed 20 | *.pid.lock 21 | 22 | # Directory for instrumented libs generated by jscoverage/JSCover 23 | lib-cov 24 | 25 | # Coverage directory used by tools like istanbul 26 | coverage 27 | 28 | # nyc test coverage 29 | .nyc_output 30 | 31 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 32 | .grunt 33 | 34 | # Bower dependency directory (https://bower.io/) 35 | bower_components 36 | 37 | # node-waf configuration 38 | .lock-wscript 39 | 40 | # Compiled binary addons (https://nodejs.org/api/addons.html) 41 | build/Release 42 | 43 | # Dependency directories 44 | node_modules/ 45 | jspm_packages/ 46 | 47 | # TypeScript v1 declaration files 48 | typings/ 49 | 50 | # Optional npm cache directory 51 | .npm 52 | 53 | # Optional eslint cache 54 | .eslintcache 55 | 56 | # Optional REPL history 57 | .node_repl_history 58 | 59 | # Output of 'npm pack' 60 | *.tgz 61 | 62 | # Yarn Integrity file 63 | .yarn-integrity 64 | 65 | # dotenv environment variables file 66 | .env 67 | 68 | # next.js build output 69 | .next 70 | -------------------------------------------------------------------------------- /.yarnrc: -------------------------------------------------------------------------------- 1 | --*.ignore-engines true 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 MO 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 all 13 | 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 THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /circle.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | jobs: 3 | build: 4 | docker: 5 | - image: circleci/node:latest 6 | branches: 7 | ignore: 8 | - gh-pages 9 | steps: 10 | - checkout 11 | - restore_cache: 12 | key: dependency-cache-{{ checksum "yarn.lock" }} 13 | - run: 14 | name: install dependences 15 | command: yarn 16 | - save_cache: 17 | key: dependency-cache-{{ checksum "yarn.lock" }} 18 | paths: 19 | - ./node_modules 20 | - run: 21 | name: test 22 | command: yarn test 23 | -------------------------------------------------------------------------------- /examples/child1/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "child1", 3 | "version": "1.0.0-alpha.3", 4 | "private": true, 5 | "description": "", 6 | "main": "nut.config.js", 7 | "scripts": { 8 | "dev": "node ../../packages/cli/bin/index.js pages dev", 9 | "build": "node ../../packages/cli/bin/index.js pages build" 10 | }, 11 | "keywords": [], 12 | "author": "", 13 | "license": "ISC" 14 | } 15 | -------------------------------------------------------------------------------- /examples/child1/pages.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | layout: 'kaola', 3 | port: 9001, 4 | output: { 5 | publicPath: 'http://127.0.0.1:9001/' 6 | }, 7 | } 8 | -------------------------------------------------------------------------------- /examples/child1/src/pages/a.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 9 | 10 | 15 | -------------------------------------------------------------------------------- /examples/child1/src/pages/b.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 9 | 10 | 12 | -------------------------------------------------------------------------------- /examples/child2/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "child2", 3 | "version": "1.0.0-alpha.3", 4 | "private": true, 5 | "description": "", 6 | "main": "nut.config.js", 7 | "scripts": { 8 | "dev": "node ../../packages/cli/bin/index.js pages dev", 9 | "build": "node ../../packages/cli/bin/index.js pages build" 10 | }, 11 | "keywords": [], 12 | "author": "", 13 | "license": "ISC" 14 | } 15 | -------------------------------------------------------------------------------- /examples/child2/pages.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | layout: 'kaola', 3 | port: 9002, 4 | output: { 5 | publicPath: 'http://127.0.0.1:9002/' 6 | }, 7 | } 8 | -------------------------------------------------------------------------------- /examples/child2/src/pages/c.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 9 | 10 | 15 | -------------------------------------------------------------------------------- /examples/child2/src/pages/d.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 9 | 10 | 12 | -------------------------------------------------------------------------------- /examples/host/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "host", 3 | "version": "1.0.0-alpha.3", 4 | "private": true, 5 | "description": "", 6 | "main": "app.js", 7 | "scripts": { 8 | "dev": "node ../../packages/cli/bin/index.js pages dev", 9 | "build": "node ../../packages/cli/bin/index.js pages build" 10 | }, 11 | "keywords": [], 12 | "author": "", 13 | "license": "ISC" 14 | } 15 | -------------------------------------------------------------------------------- /examples/host/pages.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | layout: 'now', 3 | zh: 'nut compose', 4 | router: { 5 | mode: 'history', 6 | }, 7 | compose: { 8 | nut: { 9 | service: 'https://nut.js.org', 10 | prefix: '/nut' 11 | }, 12 | todomvc: { 13 | service: 'https://fengzilong.github.io/nut-todomvc-example/', 14 | prefix: '/todomvc' 15 | } 16 | }, 17 | homepage: 'nut/pages/home', 18 | 19 | // 合并策略 20 | // composeStrategy: null, // 'default' / 'independent' 21 | // 22 | // plugins: { 23 | // login: { 24 | // alias: [ 'x', 'y', 'z' ] 25 | // } 26 | // } 27 | 28 | plugins: [ 29 | '@nut-plugins/pages-microfrontends', 30 | '@nut-plugins/pages-layout-now' 31 | ] 32 | } 33 | -------------------------------------------------------------------------------- /examples/host/src/app.js: -------------------------------------------------------------------------------- 1 | export default ctx => { 2 | ctx.api.sidebar.configure( [ 3 | { 4 | title: '菜单', 5 | children: [ 6 | { title: 'docs', path: 'nut/pages/home' }, 7 | { title: 'todomvc', path: 'todomvc/pages/home' }, 8 | ] 9 | }, 10 | ] ) 11 | } 12 | -------------------------------------------------------------------------------- /examples/host/src/public/_redirects: -------------------------------------------------------------------------------- 1 | /* /index.html 200 2 | -------------------------------------------------------------------------------- /examples/next/.browserslistrc: -------------------------------------------------------------------------------- 1 | chrome 10 2 | -------------------------------------------------------------------------------- /examples/next/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. 5 | 6 | # 1.5.0 (2020-02-29) 7 | 8 | 9 | ### Features 10 | 11 | * add modern build plugin ([#83](https://github.com/fengzilong/nut/issues/83)) ([c3539c5](https://github.com/fengzilong/nut/commit/c3539c533ba293a48b62d7255c49331975396e36)) 12 | -------------------------------------------------------------------------------- /examples/next/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "next", 3 | "private": true, 4 | "version": "1.5.1-alpha.0", 5 | "description": "", 6 | "main": "index.js", 7 | "scripts": { 8 | "dev": "node ../../packages/cli/bin/index.js pages dev --progress", 9 | "build": "node ../../packages/cli/bin/index.js pages build --progress" 10 | }, 11 | "nut": { 12 | "presets": "@nut-project/presets-alpha" 13 | }, 14 | "keywords": [], 15 | "author": "", 16 | "license": "MIT", 17 | "devDependencies": { 18 | "@nut-plugins/modern-build": "^1.0.0-alpha.2", 19 | "@nut-project/presets-alpha": "^1.0.0-alpha.20", 20 | "vue-server-renderer": "^2.6.10", 21 | "vue-template-compiler": "^2.6.10" 22 | }, 23 | "dependencies": { 24 | "vue": "^2.6.10", 25 | "vue-router": "^3.1.3" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /examples/next/pages.config.js: -------------------------------------------------------------------------------- 1 | const path = require( 'path' ) 2 | 3 | module.exports = function ( ctx ) { 4 | console.log( 'pages.config.js ctx:', ctx ) 5 | 6 | return { 7 | config: { 8 | webpack: { 9 | minimize: false, 10 | entry: path.join( __dirname, 'src/entry-client.js' ), 11 | output: {}, 12 | devServer: { 13 | port: 9000, 14 | historyApiFallback: true, 15 | }, 16 | cache: true, 17 | constants: { 18 | HELLO: JSON.stringify( 'world!!!' ) 19 | } 20 | } 21 | }, 22 | 23 | plugins: { 24 | modernBuild: { 25 | resolve: '@nut-plugins/modern-build', 26 | options: {}, 27 | }, 28 | rem: { 29 | resolve: require.resolve( './plugins/plugin-rem' ), 30 | options: { 31 | x: 1 32 | }, 33 | enable: true, 34 | }, 35 | vuessr: { 36 | enable: false, 37 | resolve: '@nut-plugins/vue-ssr', 38 | options: { 39 | entry: path.join( __dirname, 'src/entry-server.js' ), 40 | html: ` 41 | 42 | 43 | 44 | {{{ renderResourceHints() }}} 45 | 46 | {{{ renderStyles() }}} 47 | 48 | 49 | 50 | {{{ renderState() }}} 51 | {{{ renderScripts() }}} 52 | 53 | 54 | ` 55 | } 56 | } 57 | }, 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /examples/next/plugins/plugin-rem.js: -------------------------------------------------------------------------------- 1 | class RemPlugin { 2 | constructor( options ) { 3 | console.log( 'rem options', options ) 4 | } 5 | 6 | async apply( ctx ) { 7 | const { api, hook } = ctx.use( 'webpack' ) 8 | 9 | hook( 'env', env => { 10 | hook( 'dangerously_chainWebpack', config => { 11 | // console.log( 'hook dangerously_chainWebpack', config ) 12 | } ) 13 | } ) 14 | 15 | api.cheerio( $ => { 16 | console.log( $( 'title' ).html() ) 17 | $( 'title' ).text( 'Hello Plugin' ) 18 | console.log( $( 'title' ).html() ) 19 | } ) 20 | 21 | api.entry.prepend( require.resolve( './runtime' ) ) 22 | } 23 | } 24 | 25 | module.exports = RemPlugin 26 | -------------------------------------------------------------------------------- /examples/next/plugins/runtime.js: -------------------------------------------------------------------------------- 1 | console.log( 'injected runtime' ) 2 | -------------------------------------------------------------------------------- /examples/next/src/app.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 11 | 12 | 17 | -------------------------------------------------------------------------------- /examples/next/src/components/Hello.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 12 | 13 | 15 | -------------------------------------------------------------------------------- /examples/next/src/components/Home.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 12 | 13 | 15 | -------------------------------------------------------------------------------- /examples/next/src/create-app.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App.vue' 3 | import { createRouter } from './router' 4 | 5 | export function createApp () { 6 | const router = createRouter() 7 | 8 | const foo = ({ a = 1 }, b = 2, ...args) => [a,b,args]; 9 | console.log(foo); 10 | 11 | console.log( HELLO ); 12 | 13 | const app = new Vue( { 14 | router, 15 | render: h => h(App) 16 | } ) 17 | 18 | return { app, router } 19 | } 20 | -------------------------------------------------------------------------------- /examples/next/src/entry-client.js: -------------------------------------------------------------------------------- 1 | import { createApp } from './create-app' 2 | 3 | const { app, router } = createApp() 4 | 5 | router.onReady(() => { 6 | app.$mount('#app') 7 | }) 8 | -------------------------------------------------------------------------------- /examples/next/src/entry-server.js: -------------------------------------------------------------------------------- 1 | import { createApp } from './create-app' 2 | 3 | export default context => { 4 | return new Promise((resolve, reject) => { 5 | const { app, router } = createApp() 6 | 7 | router.push(context.url) 8 | 9 | router.onReady(() => { 10 | const matchedComponents = router.getMatchedComponents() 11 | if (!matchedComponents.length) { 12 | return reject({ code: 404 }) 13 | } 14 | 15 | resolve(app) 16 | }, reject) 17 | }) 18 | } 19 | -------------------------------------------------------------------------------- /examples/next/src/index.js: -------------------------------------------------------------------------------- 1 | import './index.scss' 2 | import App from './app.vue' 3 | import Vue from 'vue' 4 | 5 | // document.querySelector( '#app' ).innerHTML = ` 6 | // Hello World 7 | // ` 8 | 9 | console.log( App ) 10 | 11 | new Vue( { 12 | render: h => h( App ) 13 | } ).$mount( '#app' ) 14 | -------------------------------------------------------------------------------- /examples/next/src/index.scss: -------------------------------------------------------------------------------- 1 | html { 2 | font-size: 19px; 3 | background-color: #f2f2f2; 4 | } 5 | -------------------------------------------------------------------------------- /examples/next/src/router.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Router from 'vue-router' 3 | 4 | Vue.use( Router ) 5 | 6 | export function createRouter () { 7 | return new Router( { 8 | mode: 'history', 9 | routes: [ 10 | { name: 'home', path: '/', component: () => import( /* webpackChunkName: "home" */ './components/Home.vue' ) }, 11 | { name: 'hello', path: '/hello', component: () => import( /* webpackChunkName: "hello" */ './components/Hello.vue' ) }, 12 | ] 13 | } ) 14 | } 15 | -------------------------------------------------------------------------------- /examples/now2/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "now2", 3 | "private": true, 4 | "version": "1.0.0-alpha.3", 5 | "description": "my awesome nut project", 6 | "keywords": [], 7 | "scripts": { 8 | "dev": "node ../../packages/cli/bin/index.js pages dev", 9 | "prod": "node ../../packages/cli/bin/index.js pages build" 10 | }, 11 | "author": { 12 | "name": "fengzilong", 13 | "email": "feng_zilong@163.com" 14 | }, 15 | "license": "MIT" 16 | } 17 | -------------------------------------------------------------------------------- /examples/now2/pages.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | port: 9002, 3 | zh: 'now2', 4 | layout: 'now2', 5 | markdown: { 6 | theme: 'prism-duotone-light', 7 | }, 8 | sidebar: [ 9 | { 10 | title: 'Menu', 11 | children: [ 12 | { 13 | title: 'Menu2', 14 | children: [ 15 | { title: 'Demo', path: 'pages/demo' }, 16 | ] 17 | }, 18 | { 19 | title: 'Menu3', 20 | children: [ 21 | { title: 'Demo2', path: 'pages/demo2' }, 22 | { 23 | title: 'Leaf', 24 | children: [ 25 | { title: 'Markdown', path: 'pages/markdown' }, 26 | ] 27 | } 28 | ] 29 | }, 30 | ] 31 | }, 32 | { 33 | title: 'Menu2', 34 | children: [ 35 | { 36 | title: 'Menu3', 37 | children: [ 38 | { title: 'Demo3', path: 'pages/demo3' }, 39 | ] 40 | } 41 | ] 42 | } 43 | ], 44 | homepage: 'pages/home', 45 | } 46 | -------------------------------------------------------------------------------- /examples/now2/src/app.js: -------------------------------------------------------------------------------- 1 | export default ctx => { 2 | // 定制 pages/home 布局为 none 3 | ctx.api.page( 'pages/home' ).set( 'layout', 'none' ) 4 | } 5 | -------------------------------------------------------------------------------- /examples/now2/src/pages/demo.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | 13 | 15 | -------------------------------------------------------------------------------- /examples/now2/src/pages/demo2.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | 13 | 15 | -------------------------------------------------------------------------------- /examples/now2/src/pages/demo3.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | 13 | 15 | -------------------------------------------------------------------------------- /examples/now2/src/pages/home.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 21 | 22 | 53 | -------------------------------------------------------------------------------- /examples/now2/src/pages/markdown.md: -------------------------------------------------------------------------------- 1 | # Markdown page 2 | 3 | write your **markdown** here 4 | 5 | ```js 6 | function sayHello() { 7 | console.log( 'hello world' ) 8 | } 9 | ``` 10 | 11 | write your **markdown** here 12 | 13 | ```js 14 | function sayHello() { 15 | console.log( 'hello world' ) 16 | } 17 | ``` 18 | 19 | write your **markdown** here 20 | 21 | ```js 22 | function sayHello() { 23 | console.log( 'hello world' ) 24 | } 25 | ``` 26 | 27 | write your **markdown** here 28 | 29 | ```js 30 | function sayHello() { 31 | console.log( 'hello world' ) 32 | } 33 | ``` 34 | 35 | write your **markdown** here 36 | 37 | ```js 38 | function sayHello() { 39 | console.log( 'hello world' ) 40 | } 41 | ``` 42 | 43 | write your **markdown** here 44 | 45 | ```js 46 | function sayHello() { 47 | console.log( 'hello world' ) 48 | } 49 | ``` 50 | 51 | write your **markdown** here 52 | 53 | ```js 54 | function sayHello() { 55 | console.log( 'hello world' ) 56 | } 57 | ``` 58 | -------------------------------------------------------------------------------- /examples/now2/src/public/nut-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nut-project/nut/672e123a975dc02ffc12a5bbad31a2c5a49fc776/examples/now2/src/public/nut-logo.png -------------------------------------------------------------------------------- /examples/simple/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "plugin:vue/recommended" 3 | } 4 | -------------------------------------------------------------------------------- /examples/simple/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. 5 | 6 | # [1.1.0](https://github.com/fengzilong/nut/compare/simple@1.0.2...simple@1.1.0) (2019-09-10) 7 | 8 | 9 | ### Features 10 | 11 | * **runtime-pages:** add showBreadcrumb for layout kaola ([450a465](https://github.com/fengzilong/nut/commit/450a465)) 12 | 13 | 14 | 15 | 16 | 17 | ## [1.0.2](https://github.com/fengzilong/nut/compare/simple@1.0.1...simple@1.0.2) (2019-09-10) 18 | 19 | 20 | ### Bug Fixes 21 | 22 | * **runtime-pages:** cannot mark active for direct children of sidebar ([ead5940](https://github.com/fengzilong/nut/commit/ead5940)) 23 | -------------------------------------------------------------------------------- /examples/simple/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = function ( api ) { 2 | api.cache.never() 3 | 4 | return { 5 | plugins: [ 6 | '@babel/plugin-proposal-optional-chaining', 7 | ] 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /examples/simple/config/config.default.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | foo: 'default', 3 | bar: 'bar' 4 | } 5 | -------------------------------------------------------------------------------- /examples/simple/config/config.dev.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | foo: 'dev', 3 | } 4 | -------------------------------------------------------------------------------- /examples/simple/config/config.prod.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | foo: 'prod', 3 | } 4 | -------------------------------------------------------------------------------- /examples/simple/config/plugin.default.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | x: 1, 3 | 'builtins:layout-kaola': { 4 | showBreadcrumb: true 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /examples/simple/config/plugin.dev.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | login: { 3 | origin: 'http://10.213.11.196:7001' 4 | }, 5 | 6 | notfound: { 7 | emoji: '🌻' 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /examples/simple/config/plugin.prod.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | login: { 3 | origin: 'http://10.242.146.20:7001' 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /examples/simple/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "simple", 3 | "private": true, 4 | "version": "1.0.0-alpha.3", 5 | "description": "", 6 | "scripts": { 7 | "dev": "node ../../packages/cli/bin/index.js pages dev", 8 | "build": "node ../../packages/cli/bin/index.js pages build" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "MIT", 13 | "devDependencies": { 14 | "@babel/plugin-proposal-optional-chaining": "^7.2.0", 15 | "@nut-plugins/login": "^0.0.0", 16 | "eslint": "^5.16.0", 17 | "eslint-loader": "^2.1.2", 18 | "eslint-plugin-vue": "^5.2.2" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /examples/simple/plugins/login/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@nut-plugins/login", 3 | "version": "0.0.0", 4 | "publishConfig": { 5 | "access": "public" 6 | }, 7 | "description": "", 8 | "main": "index.js", 9 | "scripts": { 10 | }, 11 | "keywords": [], 12 | "author": "fengzilong1992@gmail.com", 13 | "repository": { 14 | "type": "git", 15 | "url": "git+https://github.com/fengzilong/nut.git" 16 | }, 17 | "bugs": { 18 | "url": "https://github.com/fengzilong/nut/issues" 19 | }, 20 | "homepage": "https://github.com/fengzilong/nut#readme", 21 | "license": "MIT" 22 | } 23 | -------------------------------------------------------------------------------- /examples/simple/plugins/login/pages.browser.js: -------------------------------------------------------------------------------- 1 | export default function( ctx, options ) { 2 | const { origin = '' } = options || {} 3 | const { api, events } = ctx 4 | 5 | async function getUser() { 6 | const response = await api.axios.get( origin + '/nut/plugin/login/user' ) 7 | const json = response.data || {} 8 | const { nickname, email } = json.body || {} 9 | 10 | return { nickname, email } 11 | } 12 | 13 | async function isLogin() { 14 | const response = await api.axios.get( origin + '/nut/plugin/login/is-login' ) 15 | const json = response.data 16 | return json.body 17 | } 18 | 19 | function toLogin() { 20 | location.replace( origin + '/nut/plugin/login/to-login' ) 21 | } 22 | 23 | async function logout() { 24 | const response = await api.axios.get( origin + '/nut/plugin/login/logout' ) 25 | const json = response.data 26 | return json.code === 200 27 | } 28 | 29 | api.expose( 'getUser', getUser ) 30 | api.expose( 'isLogin', isLogin ) 31 | api.expose( 'toLogin', toLogin ) 32 | api.expose( 'logout', logout ) 33 | 34 | events.on( 'system:before-startup', async ctx => { 35 | const isLogined = await isLogin() 36 | 37 | if ( !isLogined ) { 38 | toLogin() 39 | await delay( 1000 ) 40 | return 41 | } 42 | 43 | ctx.user = await getUser() 44 | } ) 45 | 46 | events.on( 'layout:logout', async () => { 47 | await logout() 48 | toLogin() 49 | } ) 50 | } 51 | 52 | function delay( duration = 0 ) { 53 | return new Promise( ( resolve ) => { 54 | setTimeout( () => { 55 | resolve() 56 | }, duration ) 57 | } ) 58 | } 59 | -------------------------------------------------------------------------------- /examples/simple/plugins/notfound/pages.browser.js: -------------------------------------------------------------------------------- 1 | export default function( { api, events }, options ) { 2 | api.page( 'pages/index@notfound' ).set( 'layout', 'none' ) 3 | 4 | events.on( 'route:notfound', () => { 5 | api.router.push( { 6 | page: 'pages/index' 7 | }, { scoped: true } ) 8 | } ) 9 | } 10 | -------------------------------------------------------------------------------- /examples/simple/plugins/notfound/pages/index.js: -------------------------------------------------------------------------------- 1 | export default { 2 | $$nut: function ( ctx, options = {} ) { 3 | return { 4 | mount( node ) { 5 | node.innerText = '404 ' + options.emoji 6 | }, 7 | 8 | unmount( node ) { 9 | node.innerText = '' 10 | } 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /examples/simple/plugins/test/pages.browser.js: -------------------------------------------------------------------------------- 1 | export default function ( ctx = {}, options = {} ) { 2 | const { events } = ctx 3 | 4 | events.on( 'system:before-startup', () => {} ) 5 | events.on( 'route:enabled', () => {} ) 6 | } 7 | -------------------------------------------------------------------------------- /examples/simple/src/components/demo.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 21 | 22 | 40 | -------------------------------------------------------------------------------- /examples/simple/src/components/object.js: -------------------------------------------------------------------------------- 1 | export default { 2 | hello: 'world' 3 | } 4 | -------------------------------------------------------------------------------- /examples/simple/src/pages/documents/demo.vue.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 标题测试 3 | --- 4 | 5 | import Demo from '@/components/demo' 6 | import object from '@/components/object' 7 | 8 | ## Demo 9 | 10 | ### Basic 11 | 12 | ```html 13 | { object.hello} 14 | ``` 15 | 16 | \n 17 | 18 | { object.hello } 19 | 20 | ### Square 21 | 22 | ```html 23 | { object.hello} 24 | ``` 25 | 26 | \n 27 | 28 | { object.hello } 29 | 30 | ## API 31 | 32 | | 水果 | 价格 | 数量 | 33 | | -------- | ------:|:------:| 34 | | 香蕉 | $1 | 5 | 35 | | 苹果 | $1 | 6 | 36 | | 草莓 | $1 | 7 | 37 | -------------------------------------------------------------------------------- /examples/simple/src/pages/documents/index.md: -------------------------------------------------------------------------------- 1 | ## 介绍 2 | 3 | 这个系统... 4 | 5 | ## 使用说明 6 | 7 | 8 | 9 | ```js 10 | const path = require( 'path' ) 11 | console.log( path.join( __dirname, 'index.js' ) ) 12 | ``` 13 | 14 | ## 接口说明 15 | 16 | | 水果 | 价格 | 数量 | 17 | | -------- | ------:|:------:| 18 | | 香蕉 | $1 | 5 | 19 | | 苹果 | $1 | 6 | 20 | | 草莓 | $1 | 7 | 21 | -------------------------------------------------------------------------------- /examples/simple/src/pages/documents/reference.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: title test for markdown 3 | --- 4 | 5 | ## api 指南 6 | 7 | ... 8 | -------------------------------------------------------------------------------- /examples/simple/src/pages/home/components/style.css: -------------------------------------------------------------------------------- 1 | .goods { 2 | color: #fff; 3 | } 4 | -------------------------------------------------------------------------------- /examples/simple/src/pages/home/components/style.js: -------------------------------------------------------------------------------- 1 | import './style.css' 2 | -------------------------------------------------------------------------------- /examples/simple/src/pages/home/demo/_id.js: -------------------------------------------------------------------------------- 1 | import Regular from 'regularjs' 2 | 3 | const Page = Regular.extend( { 4 | template: ` 5 |
6 | home/foo/{ $router.params.id } 7 |
8 | `, 9 | config() { 10 | 11 | }, 12 | } ) 13 | 14 | Page.$$nut = function ( ctx ) { 15 | let instance 16 | 17 | return { 18 | mount( node ) { 19 | if ( !instance ) { 20 | instance = new Page() 21 | } 22 | instance.$inject( node ) 23 | }, 24 | 25 | unmount( node ) { 26 | instance.$inject( false ) 27 | }, 28 | } 29 | } 30 | 31 | export default Page 32 | -------------------------------------------------------------------------------- /examples/simple/src/pages/home/home.js: -------------------------------------------------------------------------------- 1 | import Regular from 'regularjs' 2 | import styles from './home.module.scss' 3 | 4 | const Page = Regular.extend( { 5 | template: ` 6 |
home
7 | ` 8 | } ) 9 | 10 | Page.$$nut = function ( ctx ) { 11 | let instance 12 | 13 | return { 14 | mount( node ) { 15 | if ( !instance ) { 16 | instance = new Page() 17 | } 18 | instance.$inject( node ) 19 | 20 | const obj = { 21 | foo: { 22 | bar: { 23 | baz: 'world', 24 | }, 25 | }, 26 | }; 27 | 28 | const baz = obj?.foo?.bar?.baz; 29 | 30 | console.log( baz ) 31 | }, 32 | 33 | unmount( node ) { 34 | instance.$inject( false ) 35 | }, 36 | 37 | // beforeLeave() { 38 | // 39 | // }, 40 | 41 | enter() { 42 | import( './components/style' ).then( () => { 43 | console.log( 'style loaded' ) 44 | } ) 45 | }, 46 | } 47 | } 48 | 49 | export default Page 50 | -------------------------------------------------------------------------------- /examples/simple/src/pages/home/home.module.scss: -------------------------------------------------------------------------------- 1 | $blue: grey; 2 | 3 | .home_scss_test { 4 | color: $blue; 5 | } 6 | -------------------------------------------------------------------------------- /examples/simple/src/pages/home/index.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 37 | 38 | 45 | -------------------------------------------------------------------------------- /examples/simple/src/pages/home/react.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export default class Page extends React.Component { 4 | render() { 5 | return
react!!!
6 | } 7 | } 8 | 9 | // export default () =>
react
10 | -------------------------------------------------------------------------------- /examples/simple/src/pages/home/regular.js: -------------------------------------------------------------------------------- 1 | import Regular from 'regularjs' 2 | import './regular.styl' 3 | 4 | const Page = Regular.extend( { 5 | template: ` 6 |
7 | page written by regular { count } 8 |
9 | `, 10 | 11 | config() { 12 | this.data.count = 0 13 | }, 14 | 15 | init() { 16 | setInterval( () => { 17 | this.data.count = this.data.count + 1 18 | this.$update() 19 | }, 1000 ) 20 | } 21 | } ) 22 | 23 | Page.$$nut = function ( ctx ) { 24 | let instance 25 | 26 | return { 27 | beforeEnter( { next } ) { 28 | next() 29 | }, 30 | 31 | mount( node ) { 32 | if ( !instance ) { 33 | instance = new Page() 34 | } 35 | 36 | instance.$inject( node ) 37 | }, 38 | 39 | unmount( node ) { 40 | if ( !instance ) { 41 | return 42 | } 43 | 44 | instance.$inject( false ) 45 | }, 46 | 47 | destroy() { 48 | if ( !instance ) { 49 | return 50 | } 51 | 52 | instance.destroy() 53 | instance = null 54 | } 55 | } 56 | } 57 | 58 | export default Page 59 | -------------------------------------------------------------------------------- /examples/simple/src/pages/home/regular.styl: -------------------------------------------------------------------------------- 1 | color_blue = blue 2 | 3 | .stylus_test 4 | color: color_blue 5 | -------------------------------------------------------------------------------- /examples/simple/src/pages/home/typescript.ts: -------------------------------------------------------------------------------- 1 | let world: string = 'world' 2 | 3 | export default { 4 | $$nut: function ( ctx ) { 5 | return { 6 | mount( node ) { 7 | node.innerText = 'hello ' + world 8 | }, 9 | 10 | unmount( node ) { 11 | node.innerText = '' 12 | }, 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /examples/simple/src/pages/home/vue.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | 3 | const Page = { 4 | render( h ) { 5 | return h( 'span', {}, [ 6 | 'page written by vue ' + this.count 7 | ] ) 8 | }, 9 | data() { 10 | return { 11 | count: 0, 12 | } 13 | }, 14 | mounted() { 15 | setInterval( () => { 16 | this.count++ 17 | }, 1000 ) 18 | }, 19 | } 20 | 21 | Page.$$nut = ctx => { 22 | let instance 23 | let el 24 | 25 | return { 26 | mount( node ) { 27 | if ( !instance ) { 28 | instance = new Vue( { 29 | render: h => h( Page ) 30 | } ) 31 | } 32 | 33 | if ( !el ) { 34 | el = document.createElement( 'div' ) 35 | node.appendChild( el ) 36 | instance.$mount( el ) 37 | } else { 38 | node.appendChild( instance.$el ) 39 | } 40 | }, 41 | 42 | unmount( node ) { 43 | if ( !instance ) { 44 | return 45 | } 46 | 47 | node.removeChild( instance.$el ) 48 | }, 49 | 50 | destroy() { 51 | if ( !instance ) { 52 | return 53 | } 54 | 55 | instance.$destroy() 56 | instance = null 57 | el = null 58 | }, 59 | } 60 | } 61 | 62 | export default Page 63 | -------------------------------------------------------------------------------- /examples/simple/tsconfig.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /examples/simple/tslint.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /examples/vue/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. 5 | 6 | ## 1.0.1 (2019-12-06) 7 | 8 | **Note:** Version bump only for package vue 9 | -------------------------------------------------------------------------------- /examples/vue/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue", 3 | "private": true, 4 | "version": "1.0.2-alpha.0", 5 | "description": "", 6 | "main": "index.js", 7 | "scripts": { 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC" 13 | } 14 | -------------------------------------------------------------------------------- /examples/vue/pages.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | router: { 3 | mode: 'history', 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /examples/vue/src/app.js: -------------------------------------------------------------------------------- 1 | export default () => {} 2 | -------------------------------------------------------------------------------- /examples/vue/src/pages/hello.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 11 | 12 | 14 | -------------------------------------------------------------------------------- /examples/vue/src/pages/home.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 11 | 12 | 14 | -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "packages": [ 3 | "packages/*", 4 | "other-packages/*", 5 | "templates/*", 6 | "plugins/pages/*", 7 | "plugins/vue-ssr", 8 | "plugins/modern-build" 9 | ], 10 | "version": "independent", 11 | "useWorkspaces": true, 12 | "npmClient": "npm", 13 | "command": { 14 | "version": { 15 | "ignoreChanges": [ "**/__fixtures__/**", "**/__tests__/**", "**/*.md" ], 16 | "allowBranch": [ "master", "unstable-0.x" ], 17 | "message": "chore(release): publish" 18 | }, 19 | "publish": { 20 | "ignoreChanges": [ "**/__fixtures__/**", "**/__tests__/**", "**/*.md" ], 21 | "message": "chore(release): publish" 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /media/default-ocean.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nut-project/nut/672e123a975dc02ffc12a5bbad31a2c5a49fc776/media/default-ocean.jpg -------------------------------------------------------------------------------- /media/default-sakura.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nut-project/nut/672e123a975dc02ffc12a5bbad31a2c5a49fc776/media/default-sakura.jpg -------------------------------------------------------------------------------- /media/hmr.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nut-project/nut/672e123a975dc02ffc12a5bbad31a2c5a49fc776/media/hmr.gif -------------------------------------------------------------------------------- /media/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nut-project/nut/672e123a975dc02ffc12a5bbad31a2c5a49fc776/media/logo.png -------------------------------------------------------------------------------- /media/markdown-theme-hmr.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nut-project/nut/672e123a975dc02ffc12a5bbad31a2c5a49fc776/media/markdown-theme-hmr.gif -------------------------------------------------------------------------------- /media/now.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nut-project/nut/672e123a975dc02ffc12a5bbad31a2c5a49fc776/media/now.jpg -------------------------------------------------------------------------------- /media/route-match.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nut-project/nut/672e123a975dc02ffc12a5bbad31a2c5a49fc776/media/route-match.jpg -------------------------------------------------------------------------------- /media/saber-ocean.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nut-project/nut/672e123a975dc02ffc12a5bbad31a2c5a49fc776/media/saber-ocean.jpg -------------------------------------------------------------------------------- /media/saber-sakura.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nut-project/nut/672e123a975dc02ffc12a5bbad31a2c5a49fc776/media/saber-sakura.jpg -------------------------------------------------------------------------------- /media/social-media-preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nut-project/nut/672e123a975dc02ffc12a5bbad31a2c5a49fc776/media/social-media-preview.png -------------------------------------------------------------------------------- /media/system-events.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nut-project/nut/672e123a975dc02ffc12a5bbad31a2c5a49fc776/media/system-events.jpg -------------------------------------------------------------------------------- /other-packages/webpack-mini-css-extract/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. 5 | 6 | # [1.0.0-alpha.3](https://github.com/nut-project/nut/tree/master/packages/webpack-mini-css-extract/compare/@nut-project/mini-css-extract@1.0.0-alpha.2...@nut-project/mini-css-extract@1.0.0-alpha.3) (2019-12-06) 7 | 8 | **Note:** Version bump only for package @nut-project/mini-css-extract 9 | -------------------------------------------------------------------------------- /other-packages/webpack-mini-css-extract/lib/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "additionalProperties": true, 3 | "properties": { 4 | "publicPath": { 5 | "anyOf": [ 6 | { 7 | "type": "string" 8 | }, 9 | { 10 | "instanceof": "Function" 11 | } 12 | ] 13 | } 14 | }, 15 | "errorMessages": { 16 | "publicPath": "should be {String} or {Function} (https://github.com/webpack-contrib/mini-css-extract-plugin#publicpath)" 17 | }, 18 | "type": "object" 19 | } 20 | -------------------------------------------------------------------------------- /other-packages/webpack-mini-css-extract/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@nut-project/mini-css-extract", 3 | "version": "1.0.0-alpha.4", 4 | "publishConfig": { 5 | "access": "public" 6 | }, 7 | "description": "mini-css-extract-plugin", 8 | "keywords": [ 9 | "mini-css-extract-plugin" 10 | ], 11 | "main": "lib/index.js", 12 | "files": [ 13 | "lib", 14 | "yarn.lock", 15 | "README.md" 16 | ], 17 | "engines": { 18 | "node": ">=8.9.0" 19 | }, 20 | "repository": "https://github.com/nut-project/nut/tree/master/packages/webpack-mini-css-extract", 21 | "homepage": "http://nut.js.org", 22 | "bugs": { 23 | "url": "https://github.com/nut-project/nut/issues/new/choose" 24 | }, 25 | "scripts": {}, 26 | "author": { 27 | "name": "fengzilong", 28 | "email": "fengzilong1992@gmail.com", 29 | "url": "https://github.com/fengzilong" 30 | }, 31 | "license": "MIT", 32 | "peerDependencies": { 33 | "webpack": "^4.4.0" 34 | }, 35 | "dependencies": { 36 | "loader-utils": "^1.2.3", 37 | "normalize-url": "^4.3.0", 38 | "schema-utils": "^1.0.0", 39 | "webpack-sources": "^1.3.0" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /other-packages/webpack-virtual-modules/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. 5 | 6 | # [1.0.0-alpha.3](https://github.com/nut-project/nut/tree/master/packages/webpack-virtual-modules/compare/@nut-project/webpack-virtual-modules@1.0.0-alpha.2...@nut-project/webpack-virtual-modules@1.0.0-alpha.3) (2019-12-06) 7 | 8 | **Note:** Version bump only for package @nut-project/webpack-virtual-modules 9 | -------------------------------------------------------------------------------- /other-packages/webpack-virtual-modules/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@nut-project/webpack-virtual-modules", 3 | "version": "1.0.0-alpha.4", 4 | "publishConfig": { 5 | "access": "public" 6 | }, 7 | "description": "webpack-virtual-modules", 8 | "keywords": [ 9 | "webpack", 10 | "virtual", 11 | "modules" 12 | ], 13 | "main": "lib/index.js", 14 | "files": [ 15 | "lib", 16 | "README.md" 17 | ], 18 | "engines": { 19 | "node": ">=8.9.0" 20 | }, 21 | "repository": "https://github.com/nut-project/nut/tree/master/packages/webpack-virtual-modules", 22 | "homepage": "http://nut.js.org", 23 | "bugs": { 24 | "url": "https://github.com/nut-project/nut/issues/new/choose" 25 | }, 26 | "scripts": {}, 27 | "author": { 28 | "name": "fengzilong", 29 | "email": "fengzilong1992@gmail.com", 30 | "url": "https://github.com/fengzilong" 31 | }, 32 | "license": "MIT", 33 | "dependencies": { 34 | "debug": "^4.1.1" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /packages/babel-preset/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. 5 | 6 | # 1.0.0-alpha.1 (2020-02-29) 7 | 8 | 9 | ### Features 10 | 11 | * add modern build plugin ([#83](https://github.com/nut-project/nut/tree/master/packages/babel-preset/issues/83)) ([c3539c5](https://github.com/nut-project/nut/tree/master/packages/babel-preset/commit/c3539c533ba293a48b62d7255c49331975396e36)) 12 | -------------------------------------------------------------------------------- /packages/babel-preset/lib/index.js: -------------------------------------------------------------------------------- 1 | const path = require( 'path' ) 2 | 3 | module.exports = api => { 4 | const isModern = api.caller( caller => Boolean( caller ) && caller.isModern ) 5 | 6 | return { 7 | sourceType: 'unambiguous', 8 | presets: [ 9 | // replace preset-env with preset-modules in modern mode 10 | isModern ? 11 | [ 12 | require.resolve( '@babel/preset-modules' ), 13 | { loose: true } 14 | ] : 15 | [ 16 | require.resolve( '@babel/preset-env' ), 17 | { 18 | // debug: true, 19 | modules: false, // hand over to webpack 20 | } 21 | ] 22 | ].filter( Boolean ), 23 | plugins: [ 24 | [ 25 | require.resolve( '@babel/plugin-transform-runtime' ), 26 | { 27 | helpers: true, 28 | regenerator: !isModern, 29 | absoluteRuntime: path.dirname( 30 | require.resolve( '@babel/runtime/package.json' ) 31 | ), 32 | // specify version can reduce bundle size 33 | version: require( '@babel/runtime/package.json' ).version 34 | } 35 | ], 36 | require.resolve( '@babel/plugin-syntax-dynamic-import' ), 37 | [ 38 | require.resolve( '@babel/plugin-proposal-object-rest-spread' ), 39 | { useBuiltIns: true } 40 | ], 41 | ], 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /packages/babel-preset/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@nut-project/babel-preset", 3 | "version": "1.0.0-alpha.2", 4 | "publishConfig": { 5 | "access": "public" 6 | }, 7 | "description": "babel preset for nut", 8 | "keywords": [ 9 | "nut", 10 | "babel" 11 | ], 12 | "main": "lib/index.js", 13 | "files": [ 14 | "lib" 15 | ], 16 | "engines": { 17 | "node": ">=8.9.0" 18 | }, 19 | "repository": "https://github.com/nut-project/nut/tree/master/packages/babel-preset", 20 | "homepage": "http://nut.js.org", 21 | "bugs": { 22 | "url": "https://github.com/nut-project/nut/issues/new/choose" 23 | }, 24 | "scripts": {}, 25 | "author": { 26 | "name": "fengzilong", 27 | "email": "fengzilong1992@gmail.com", 28 | "url": "https://github.com/fengzilong" 29 | }, 30 | "license": "MIT", 31 | "dependencies": { 32 | "@babel/plugin-proposal-object-rest-spread": "^7.7.4", 33 | "@babel/plugin-syntax-dynamic-import": "^7.7.4", 34 | "@babel/plugin-transform-runtime": "^7.7.4", 35 | "@babel/preset-env": "^7.7.4", 36 | "@babel/preset-modules": "^0.1.3", 37 | "@babel/runtime": "^7.7.4" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /packages/cli-pages/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. 5 | 6 | # [1.0.0-alpha.7](https://github.com/nut-project/nut/tree/master/packages/cli/compare/@nut-project/cli-pages@1.0.0-alpha.6...@nut-project/cli-pages@1.0.0-alpha.7) (2019-12-16) 7 | 8 | **Note:** Version bump only for package @nut-project/cli-pages 9 | 10 | 11 | 12 | 13 | 14 | # [1.0.0-alpha.6](https://github.com/nut-project/nut/tree/master/packages/cli/compare/@nut-project/cli-pages@1.0.0-alpha.5...@nut-project/cli-pages@1.0.0-alpha.6) (2019-12-13) 15 | 16 | **Note:** Version bump only for package @nut-project/cli-pages 17 | 18 | 19 | 20 | 21 | 22 | # [1.0.0-alpha.5](https://github.com/nut-project/nut/tree/master/packages/cli/compare/@nut-project/cli-pages@1.0.0-alpha.4...@nut-project/cli-pages@1.0.0-alpha.5) (2019-12-11) 23 | 24 | **Note:** Version bump only for package @nut-project/cli-pages 25 | 26 | 27 | 28 | 29 | 30 | # 1.0.0-alpha.4 (2019-12-06) 31 | 32 | **Note:** Version bump only for package @nut-project/cli-pages 33 | -------------------------------------------------------------------------------- /packages/cli-pages/lib/index.js: -------------------------------------------------------------------------------- 1 | const { CLI } = require( '@nut-project/core' ) 2 | 3 | class PagesCLI extends CLI { 4 | static name() { 5 | return 'pages' 6 | } 7 | 8 | commands() { 9 | return [ 10 | { command: 'dev', description: 'Build in development mode' }, 11 | { command: 'build', description: 'Build in production mode' } 12 | ] 13 | } 14 | } 15 | 16 | module.exports = PagesCLI 17 | -------------------------------------------------------------------------------- /packages/cli-pages/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@nut-project/cli-pages", 3 | "version": "1.0.0-alpha.8", 4 | "publishConfig": { 5 | "access": "public" 6 | }, 7 | "description": "A framework born for micro frontends", 8 | "keywords": [ 9 | "microfrontends", 10 | "micro", 11 | "frontend", 12 | "architecture", 13 | "spa", 14 | "cli", 15 | "static site generator", 16 | "hmr" 17 | ], 18 | "main": "lib/index.js", 19 | "files": [ 20 | "lib", 21 | "yarn.lock", 22 | "README.md" 23 | ], 24 | "engines": { 25 | "node": ">=8.9.0" 26 | }, 27 | "repository": "https://github.com/nut-project/nut/tree/master/packages/cli", 28 | "homepage": "http://nut.js.org", 29 | "bugs": { 30 | "url": "https://github.com/nut-project/nut/issues/new/choose" 31 | }, 32 | "scripts": { 33 | "prepublishOnly": "cp ../../README.md ./README.md" 34 | }, 35 | "author": { 36 | "name": "fengzilong", 37 | "email": "fengzilong1992@gmail.com", 38 | "url": "https://github.com/fengzilong" 39 | }, 40 | "license": "MIT", 41 | "dependencies": { 42 | "@nut-project/core": "^1.0.0-alpha.8" 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /packages/cli/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. 5 | 6 | # [1.0.0-alpha.7](https://github.com/nut-project/nut/tree/master/packages/cli/compare/@nut-project/cli@1.0.0-alpha.6...@nut-project/cli@1.0.0-alpha.7) (2019-12-16) 7 | 8 | **Note:** Version bump only for package @nut-project/cli 9 | 10 | 11 | 12 | 13 | 14 | # [1.0.0-alpha.6](https://github.com/nut-project/nut/tree/master/packages/cli/compare/@nut-project/cli@1.0.0-alpha.5...@nut-project/cli@1.0.0-alpha.6) (2019-12-13) 15 | 16 | **Note:** Version bump only for package @nut-project/cli 17 | 18 | 19 | 20 | 21 | 22 | # [1.0.0-alpha.5](https://github.com/nut-project/nut/tree/master/packages/cli/compare/@nut-project/cli@1.0.0-alpha.4...@nut-project/cli@1.0.0-alpha.5) (2019-12-11) 23 | 24 | **Note:** Version bump only for package @nut-project/cli 25 | 26 | 27 | 28 | 29 | 30 | # [1.0.0-alpha.4](https://github.com/nut-project/nut/tree/master/packages/cli/compare/@nut-project/cli@1.0.0-alpha.3...@nut-project/cli@1.0.0-alpha.4) (2019-12-06) 31 | 32 | **Note:** Version bump only for package @nut-project/cli 33 | -------------------------------------------------------------------------------- /packages/cli/bin/index.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const { startup } = require( '@nut-project/core' ) 4 | const { config } = require( '@nut-project/dev-utils' ) 5 | 6 | ;( async function () { 7 | const userConfigManager = config( 'nut' ) 8 | const userConfig = await userConfigManager.get() 9 | 10 | await startup( userConfig ) 11 | } )() 12 | -------------------------------------------------------------------------------- /packages/cli/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@nut-project/cli", 3 | "version": "1.0.0-alpha.8", 4 | "publishConfig": { 5 | "access": "public" 6 | }, 7 | "description": "A framework born for micro frontends", 8 | "keywords": [ 9 | "microfrontends", 10 | "micro", 11 | "frontend", 12 | "architecture", 13 | "spa", 14 | "cli", 15 | "static site generator", 16 | "hmr" 17 | ], 18 | "bin": { 19 | "nut": "bin/index.js" 20 | }, 21 | "files": [ 22 | "bin", 23 | "yarn.lock", 24 | "README.md" 25 | ], 26 | "engines": { 27 | "node": ">=8.9.0" 28 | }, 29 | "repository": "https://github.com/nut-project/nut/tree/master/packages/cli", 30 | "homepage": "http://nut.js.org", 31 | "bugs": { 32 | "url": "https://github.com/nut-project/nut/issues/new/choose" 33 | }, 34 | "scripts": { 35 | "prepublishOnly": "cp ../../README.md ./README.md" 36 | }, 37 | "author": { 38 | "name": "fengzilong", 39 | "email": "fengzilong1992@gmail.com", 40 | "url": "https://github.com/fengzilong" 41 | }, 42 | "license": "MIT", 43 | "dependencies": { 44 | "@nut-project/core": "^1.0.0-alpha.8", 45 | "@nut-project/dev-utils": "^1.0.0-alpha.4" 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /packages/core/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. 5 | 6 | # [1.0.0-alpha.7](https://github.com/nut-project/nut/compare/@nut-project/core@1.0.0-alpha.6...@nut-project/core@1.0.0-alpha.7) (2019-12-16) 7 | 8 | 9 | ### Bug Fixes 10 | 11 | * allow absence of config file ([d094fcd](https://github.com/nut-project/nut/commit/d094fcd920c634f8367f8ff7f9b6d240349b1e18)) 12 | 13 | 14 | 15 | 16 | 17 | # [1.0.0-alpha.6](https://github.com/nut-project/nut/compare/@nut-project/core@1.0.0-alpha.5...@nut-project/core@1.0.0-alpha.6) (2019-12-13) 18 | 19 | 20 | ### Bug Fixes 21 | 22 | * use vue-server-renderer in user project ([aa86bdd](https://github.com/nut-project/nut/commit/aa86bdd0694478949bdfeada0dc63229de534ecc)) 23 | 24 | 25 | 26 | 27 | 28 | # [1.0.0-alpha.5](https://github.com/nut-project/nut/compare/@nut-project/core@1.0.0-alpha.4...@nut-project/core@1.0.0-alpha.5) (2019-12-11) 29 | 30 | 31 | ### Features 32 | 33 | * support disable plugin ([8719a29](https://github.com/nut-project/nut/commit/8719a29041ae0771f27b53f0d3786a2060535b10)) 34 | 35 | 36 | 37 | 38 | 39 | # [1.0.0-alpha.4](https://github.com/nut-project/nut/compare/@nut-project/core@1.0.0-alpha.2...@nut-project/core@1.0.0-alpha.4) (2019-12-06) 40 | 41 | **Note:** Version bump only for package @nut-project/core 42 | -------------------------------------------------------------------------------- /packages/core/lib/index.js: -------------------------------------------------------------------------------- 1 | exports.CLI = require( './cli' ) 2 | exports.Driver = require( './driver' ) 3 | exports.startup = require( './startup' ) 4 | -------------------------------------------------------------------------------- /packages/core/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@nut-project/core", 3 | "version": "1.0.0-alpha.8", 4 | "description": "", 5 | "main": "lib/index.js", 6 | "scripts": {}, 7 | "keywords": [], 8 | "author": { 9 | "name": "fengzilong", 10 | "email": "fengzilong1992@gmail.com", 11 | "url": "https://github.com/fengzilong" 12 | }, 13 | "license": "MIT", 14 | "engines": { 15 | "node": ">=8.9.0" 16 | }, 17 | "dependencies": { 18 | "@nut-project/dev-utils": "^1.0.0-alpha.4", 19 | "cac": "^6.5.3", 20 | "chokidar": "^3.1.0", 21 | "exit": "^0.1.2", 22 | "fast-memoize": "^2.5.1", 23 | "import-fresh": "^3.2.1", 24 | "please-upgrade-node": "^3.2.0", 25 | "superstruct": "^0.8.2", 26 | "tapable": "^1.1.3", 27 | "v8-compile-cache": "^2.1.0" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /packages/dev-utils/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. 5 | 6 | # 1.0.0-alpha.3 (2019-12-06) 7 | 8 | **Note:** Version bump only for package @nut-project/dev-utils 9 | -------------------------------------------------------------------------------- /packages/dev-utils/lib/config.js: -------------------------------------------------------------------------------- 1 | const cosmiconfig = require( 'cosmiconfig' ) 2 | const logger = require( './logger' ) 3 | 4 | class Config { 5 | constructor( name ) { 6 | this._name = name 7 | } 8 | 9 | name() { 10 | return this._name 11 | } 12 | 13 | async check() { 14 | const loaded = await this.load() 15 | 16 | if ( !loaded ) { 17 | logger.error( `No config file found ( e.g. ${ this._name + '.config.js' } )\n` ) 18 | process.exit( 0 ) 19 | } 20 | } 21 | 22 | load() { 23 | return this._load() 24 | } 25 | 26 | loadSync() { 27 | return this._load( { sync: true } ) 28 | } 29 | 30 | _load( options = {} ) { 31 | const sync = options.sync 32 | 33 | const name = this.name() 34 | 35 | if ( !this._explorer ) { 36 | this._explorer = cosmiconfig( name, { cache: false } ) 37 | } 38 | 39 | if ( sync ) { 40 | return this._explorer.searchSync() 41 | } 42 | return this._explorer.search() 43 | } 44 | 45 | async getFile() { 46 | const loaded = await this.load() 47 | 48 | return loaded && loaded.filepath 49 | } 50 | 51 | async get() { 52 | const loaded = await this.load() 53 | return loaded && loaded.config 54 | } 55 | } 56 | 57 | const instances = {} 58 | function singleton( name ) { 59 | if ( !name ) { 60 | return 61 | } 62 | 63 | if ( !instances[ name ] ) { 64 | instances[ name ] = new Config( name ) 65 | } 66 | 67 | return instances[ name ] 68 | } 69 | 70 | module.exports = name => singleton( name ) 71 | -------------------------------------------------------------------------------- /packages/dev-utils/lib/index.js: -------------------------------------------------------------------------------- 1 | exports.utils = require( './utils' ) 2 | exports.logger = require( './logger' ) 3 | exports.config = require( './config' ) 4 | exports.openBrowser = require( './open-browser' ) 5 | exports.colors = require( 'chalk' ) 6 | exports.detectPort = require( 'detect-port' ) 7 | exports.install = require( 'install-packages' ) 8 | exports.localRequire = require( './local-require' ) 9 | -------------------------------------------------------------------------------- /packages/dev-utils/lib/local-require.js: -------------------------------------------------------------------------------- 1 | const importFrom = require( 'import-from' ) 2 | 3 | module.exports = importFrom.bind( null, process.cwd() ) 4 | -------------------------------------------------------------------------------- /packages/dev-utils/lib/logger.js: -------------------------------------------------------------------------------- 1 | const { Signale } = require( 'signale' ) 2 | 3 | module.exports = new Signale( { 4 | scope: '', 5 | types: {} 6 | } ) 7 | -------------------------------------------------------------------------------- /packages/dev-utils/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@nut-project/dev-utils", 3 | "version": "1.0.0-alpha.4", 4 | "publishConfig": { 5 | "access": "public" 6 | }, 7 | "description": "A framework born for micro frontends", 8 | "keywords": [ 9 | "microfrontends", 10 | "micro", 11 | "frontend", 12 | "architecture", 13 | "spa", 14 | "cli", 15 | "static site generator", 16 | "hmr" 17 | ], 18 | "main": "lib/index.js", 19 | "files": [ 20 | "bin", 21 | "lib", 22 | "yarn.lock", 23 | "README.md" 24 | ], 25 | "engines": { 26 | "node": ">=8.9.0" 27 | }, 28 | "repository": "https://github.com/nut-project/nut/tree/master/packages/gatherer", 29 | "homepage": "http://nut.js.org", 30 | "bugs": { 31 | "url": "https://github.com/nut-project/nut/issues/new/choose" 32 | }, 33 | "scripts": { 34 | "prepublishOnly": "cp ../../README.md ./README.md" 35 | }, 36 | "author": { 37 | "name": "fengzilong", 38 | "email": "fengzilong1992@gmail.com", 39 | "url": "https://github.com/fengzilong" 40 | }, 41 | "license": "MIT", 42 | "dependencies": { 43 | "chalk": "^2.4.2", 44 | "cosmiconfig": "^5.2.1", 45 | "cross-spawn": "^7.0.1", 46 | "deepmerge": "^4.0.0", 47 | "detect-port": "^1.3.0", 48 | "globby": "^10.0.1", 49 | "gradient-string": "^1.2.0", 50 | "import-from": "^3.0.0", 51 | "install-packages": "^0.2.5", 52 | "open": "^7.0.0", 53 | "signale": "^1.4.0" 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /packages/driver-pages/.gitignore: -------------------------------------------------------------------------------- 1 | note.md 2 | -------------------------------------------------------------------------------- /packages/driver-pages/lib/get-pages.js: -------------------------------------------------------------------------------- 1 | const path = require( 'path' ) 2 | const globby = require( 'globby' ) 3 | 4 | module.exports = async function getPages( root ) { 5 | let files = [] 6 | 7 | try { 8 | const patterns = [ 9 | '.js', 10 | '.md', 11 | '.vue', 12 | '.jsx', 13 | '.ts', 14 | ].map( ext => `pages/**/*${ ext }` ) 15 | 16 | files = await globby( patterns, { 17 | cwd: root, 18 | onlyFiles: true, 19 | deep: Infinity, 20 | } ) 21 | } catch ( e ) {} 22 | 23 | const promises = files 24 | .sort( ( a, b ) => { 25 | if ( a < b ) { 26 | return 1 27 | } 28 | 29 | if ( a > b ) { 30 | return -1 31 | } 32 | 33 | return 0 34 | } ) 35 | .map( async file => { 36 | return { 37 | context: root, 38 | location: path.join( root, file ), 39 | } 40 | } ) 41 | 42 | return await Promise.all( promises ) 43 | } 44 | -------------------------------------------------------------------------------- /packages/driver-pages/lib/index.js: -------------------------------------------------------------------------------- 1 | const pkg = require( '../package.json' ) 2 | const Driver = require( './driver' ) 3 | 4 | exports.name = pkg.name 5 | exports.version = pkg.version 6 | exports.scope = 'pages' 7 | exports.apply = function ( { register, scope } ) { 8 | register( cli => new Driver( { cli, scope } ).apply() ) 9 | } 10 | -------------------------------------------------------------------------------- /packages/driver-pages/lib/runtime/context.js: -------------------------------------------------------------------------------- 1 | import app from '#artifacts/app' 2 | import pages from '#artifacts/pages' 3 | import routes from '#artifacts/routes' 4 | import pluginOptions from '#artifacts/pluginOptions' 5 | import events from './events' 6 | import exposeUse from './expose-use' 7 | 8 | const context = { 9 | app, 10 | pages, 11 | routes, 12 | events, 13 | ...exposeUse, 14 | } 15 | 16 | if ( module.hot ) { 17 | module.hot.accept( '#artifacts/app', () => { 18 | events.emit( 'dev:hot-accept-app', app ) 19 | } ) 20 | module.hot.accept( '#artifacts/pages', () => { 21 | events.emit( 'dev:hot-accept-pages', pages ) 22 | } ) 23 | module.hot.accept( '#artifacts/routes', () => { 24 | events.emit( 'dev:hot-accept-routes', routes ) 25 | } ) 26 | module.hot.accept( '#artifacts/pluginOptions', () => { 27 | events.emit( 'dev:hot-accept-pluginOptions', pluginOptions ) 28 | } ) 29 | } 30 | 31 | export default context 32 | -------------------------------------------------------------------------------- /packages/driver-pages/lib/runtime/entry.js: -------------------------------------------------------------------------------- 1 | import context from '#context' 2 | import runtime from '#runtime' 3 | 4 | runtime( context ) 5 | -------------------------------------------------------------------------------- /packages/driver-pages/lib/runtime/expose-use.js: -------------------------------------------------------------------------------- 1 | export default { 2 | _exposed: {}, 3 | 4 | expose( scope, name, value ) { 5 | const exposed = this._exposed || {} 6 | 7 | exposed[ scope ] = exposed[ scope ] || {} 8 | exposed[ scope ][ name ] = value 9 | 10 | this._exposed = exposed 11 | }, 12 | 13 | use( scope, name, ...args ) { 14 | if ( !this._exposed || !this._exposed[ scope ] ) { 15 | return 16 | } 17 | 18 | const exposed = this._exposed[ scope ] 19 | const method = exposed[ name ] 20 | 21 | if ( !method ) { 22 | return 23 | } 24 | 25 | if ( typeof method === 'function' ) { 26 | return method( ...args ) 27 | } 28 | 29 | return method 30 | }, 31 | } 32 | -------------------------------------------------------------------------------- /packages/driver-pages/lib/runtime/fake-runtime.js: -------------------------------------------------------------------------------- 1 | export default context => { 2 | console.log( 'Default runtime is working' ) 3 | console.log( context ) 4 | } 5 | -------------------------------------------------------------------------------- /packages/driver-pages/lib/webpack/dev.js: -------------------------------------------------------------------------------- 1 | const { webpack } = require( '@nut-project/webpack' ) 2 | const CaseSensitivePathsPlugin = require( 'case-sensitive-paths-webpack-plugin' ) 3 | const css = require( './css' ) 4 | 5 | module.exports = function ( config ) { 6 | css( config, 'development' ) 7 | 8 | config.mode( 'development' ) 9 | config.devtool( 'cheap-module-source-map' ) 10 | config.output 11 | .filename( '[name].[hash:16].js' ) 12 | config 13 | .plugin( 'hot' ) 14 | .use( webpack.HotModuleReplacementPlugin ) // eslint-disable-line 15 | config.plugin( 'case-sensitive-paths' ) 16 | .use( CaseSensitivePathsPlugin ) 17 | 18 | return config 19 | } 20 | -------------------------------------------------------------------------------- /packages/driver-pages/lib/webpack/template.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <%= htmlWebpackPlugin.options.title %> 5 | 6 | 7 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /packages/driver-pages/lib/webpack/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "sourceMap": true 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/driver-webpack/lib/schema.js: -------------------------------------------------------------------------------- 1 | module.exports = function ( { struct } ) { 2 | const output = struct.object( { 3 | path: 'string?', 4 | clean: 'boolean?', 5 | html: struct.object( { 6 | title: 'string?', 7 | filename: 'string?', 8 | favicon: 'string?', 9 | template: 'string?', 10 | }, {} ), 11 | publicPath: 'string?', 12 | }, {} ) 13 | 14 | const babel = struct.object( { 15 | transpileModules: [ 'string' ], 16 | }, { 17 | transpileModules: [] 18 | } ) 19 | 20 | const devServer = struct.object( { 21 | host: 'string?', 22 | port: struct.optional( 'string | number' ), 23 | historyApiFallback: struct.optional( 'boolean | object' ), 24 | https: struct.optional( 'boolean | object' ), 25 | proxy: 'object?', 26 | }, {} ) 27 | 28 | const htmlPluginOptions = struct.object( { 29 | entry: 'string', 30 | title: 'string?', 31 | filename: 'string?', 32 | favicon: 'string?', 33 | template: 'string?', 34 | } ) 35 | 36 | const pages = struct.record( [ 37 | 'string', 38 | htmlPluginOptions 39 | ], {} ) 40 | 41 | return { 42 | entry: 'string?', 43 | pages, 44 | output, 45 | babel, 46 | devServer, 47 | constants: struct.record( [ 'string', 'string | number | boolean' ], {} ), 48 | alias: struct.record( [ 'string', 'string' ], {} ), 49 | parallel: 'boolean?', 50 | minimize: 'boolean?', 51 | cache: 'boolean?', 52 | fast: 'boolean?', 53 | css: struct.object( { 54 | extract: 'boolean?' 55 | }, {} ), 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /packages/driver-webpack/lib/webpack/analyze.js: -------------------------------------------------------------------------------- 1 | const BundleAnalyzerPlugin = require( 'webpack-bundle-analyzer' ).BundleAnalyzerPlugin 2 | 3 | exports.extend = function ( config, context ) { 4 | const analyze = context.cliOptions && context.cliOptions.analyze 5 | 6 | if ( analyze ) { 7 | config 8 | .plugin( 'bundle-analyzer' ) 9 | .use( BundleAnalyzerPlugin ) 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /packages/driver-webpack/lib/webpack/babel.js: -------------------------------------------------------------------------------- 1 | const createInclude = require( './shared/create-include' ) 2 | const parallel = require( './shared/parallel' ) 3 | const threadLoader = require( 'thread-loader' ) 4 | const getCacheConfig = require( './shared/get-cache-config' ) 5 | 6 | exports.extend = function ( config, context = {} ) { 7 | const { env, userConfig = {} } = context 8 | const { babel = {} } = userConfig 9 | const cache = userConfig.cache 10 | 11 | const rule = config.module.rule( 'js' ) 12 | 13 | rule.test( [ /\.m?js$/, /\.jsx$/ ] ) 14 | 15 | rule.include.add( createInclude( babel && babel.transpileModules ) ) 16 | 17 | if ( userConfig.parallel ) { 18 | threadLoader.warmup( {}, [ 19 | require.resolve( './babel/loader' ) 20 | ] ) 21 | parallel( rule ) 22 | } 23 | 24 | const babelOptions = { 25 | cacheCompression: env === 'production', 26 | } 27 | 28 | const babelCacheConfig = getCacheConfig( `nut-babel-loader`, { 29 | '@babel/core': require( '@babel/core/package.json' ).version, 30 | 'babel-loader': require( 'babel-loader/package.json' ).version, 31 | } ) 32 | 33 | if ( typeof cache === 'undefined' ) { 34 | // by default only enable cache in development 35 | if ( env === 'development' ) { 36 | Object.assign( babelOptions, babelCacheConfig ) 37 | } 38 | } else if ( cache === true ) { 39 | Object.assign( babelOptions, babelCacheConfig ) 40 | } 41 | 42 | rule.use( 'babel' ) 43 | .loader( require.resolve( './babel/loader' ) ) 44 | .options( babelOptions ) 45 | } 46 | -------------------------------------------------------------------------------- /packages/driver-webpack/lib/webpack/babel/loader.js: -------------------------------------------------------------------------------- 1 | const babelLoader = require( 'babel-loader' ) 2 | 3 | const overrides = {} 4 | 5 | module.exports = babelLoader.custom( () => { 6 | return overrides 7 | } ) 8 | 9 | module.exports.override = function ( getOverrides = () => {} ) { 10 | let localBabel 11 | 12 | babelLoader.custom( babel => { 13 | localBabel = babel 14 | } ) 15 | 16 | Object.assign( overrides, getOverrides( localBabel ) || {} ) 17 | } 18 | -------------------------------------------------------------------------------- /packages/driver-webpack/lib/webpack/babel/preset.js: -------------------------------------------------------------------------------- 1 | module.exports = require( '@nut-project/babel-preset' ) 2 | -------------------------------------------------------------------------------- /packages/driver-webpack/lib/webpack/cache.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nut-project/nut/672e123a975dc02ffc12a5bbad31a2c5a49fc776/packages/driver-webpack/lib/webpack/cache.js -------------------------------------------------------------------------------- /packages/driver-webpack/lib/webpack/clean.js: -------------------------------------------------------------------------------- 1 | const { CleanWebpackPlugin } = require( 'clean-webpack-plugin' ) 2 | 3 | exports.extend = function ( config, context = {} ) { 4 | const { userConfig = {} } = context 5 | const clean = userConfig.output && userConfig.output.clean 6 | 7 | // clean by default 8 | if ( clean !== false ) { 9 | config.plugin( 'clean' ) 10 | .use( CleanWebpackPlugin ) 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /packages/driver-webpack/lib/webpack/copy.js: -------------------------------------------------------------------------------- 1 | const path = require( 'path' ) 2 | const CopyPlugin = require( 'copy-webpack-plugin' ) 3 | 4 | exports.extend = function ( config ) { 5 | config 6 | .plugin( 'copy' ) 7 | .use( CopyPlugin, [ 8 | [ 9 | { 10 | from: { 11 | glob: '**/*', 12 | dot: true 13 | }, 14 | to: '.', 15 | ignore: [ '.DS_Store' ], 16 | context: path.join( process.cwd(), 'public' ) 17 | } 18 | ], 19 | {} 20 | ] ) 21 | } 22 | 23 | exports.expose = function ( driver ) { 24 | driver.expose( 'copy', ( copies = [] ) => { 25 | driver.useHook( 'dangerously_chainWebpack', config => { 26 | copies.forEach( copy => { 27 | config 28 | .plugin( 'copy' ) 29 | .tap( ( args = [] ) => { 30 | args[ 0 ] = args[ 0 ] || [] 31 | args[ 0 ].push( { 32 | from: { 33 | glob: copy.from, 34 | dot: true 35 | }, 36 | to: copy.to || '.', 37 | toType: copy.toType, 38 | context: copy.context || process.cwd(), 39 | ignore: [ '.DS_Store' ] 40 | } ) 41 | 42 | return args 43 | } ) 44 | } ) 45 | } ) 46 | } ) 47 | } 48 | -------------------------------------------------------------------------------- /packages/driver-webpack/lib/webpack/css.js: -------------------------------------------------------------------------------- 1 | const MiniCssExtractPlugin = require( 'mini-css-extract-plugin' ) 2 | const { applyCSSRule } = require( './shared/apply-css-rule' ) 3 | const localResolve = require( './shared/local-resolve' ) 4 | const localRequire = require( './shared/local-require' ) 5 | 6 | exports.extend = function ( config, context = {} ) { 7 | const { env = '', userConfig = {} } = context 8 | 9 | let extractCSS = userConfig && userConfig.css && userConfig.css.extract 10 | if ( typeof extractCSS !== 'boolean' ) { 11 | extractCSS = env === 'production' 12 | } 13 | 14 | // perfer local sass/node-sass, fallback to sass in driver-webpack 15 | // as dart-sass does not support /deep/ syntax(use ::v-deep instead) 16 | // for more details, see https://github.com/vuejs/vue-cli/issues/3399 17 | const scssOptions = {} 18 | 19 | if ( ( localResolve( 'node-sass' ) ) ) { 20 | scssOptions.implementation = localRequire( 'node-sass' ) 21 | } else if ( ( localResolve( 'sass' ) ) ) { 22 | scssOptions.implementation = localRequire( 'sass' ) 23 | } else { 24 | scssOptions.implementation = require( 'sass' ) 25 | } 26 | 27 | const sassOptions = Object.assign( {}, scssOptions, { 28 | indentedSyntax: true, 29 | } ) 30 | 31 | applyCSSRule( config, 'css', /\.css$/, null, {}, extractCSS ) 32 | 33 | applyCSSRule( config, 'less', /\.less$/, 'less-loader', {}, extractCSS ) 34 | 35 | applyCSSRule( config, 'scss', /\.scss$/, 'sass-loader', scssOptions, extractCSS ) 36 | 37 | applyCSSRule( config, 'sass', /\.sass$/, 'sass-loader', sassOptions, extractCSS ) 38 | 39 | applyCSSRule( config, 'mcss', /\.mcss$/, 'mcss-loader', {}, extractCSS ) 40 | 41 | applyCSSRule( config, 'stylus', /\.styl(us)?$/, 'stylus-loader', { 42 | preferPathResolver: 'webpack', 43 | }, extractCSS ) 44 | 45 | if ( extractCSS ) { 46 | config 47 | .plugin( 'extract-css' ) 48 | .use( MiniCssExtractPlugin, [ { 49 | filename: `[name].[contenthash].css`, 50 | chunkFilename: `[name].[contenthash].css`, 51 | } ] ) 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /packages/driver-webpack/lib/webpack/define.js: -------------------------------------------------------------------------------- 1 | const { webpack } = require( '@nut-project/webpack' ) 2 | 3 | exports.extend = function ( config, context = {} ) { 4 | const { userConfig = {} } = context 5 | const constants = userConfig.constants || {} 6 | 7 | config.plugin( 'define' ) 8 | .use( webpack.DefinePlugin, [ constants ] ) 9 | } 10 | 11 | exports.expose = function ( driver ) { 12 | driver.expose( 'constant', ( key, value ) => { 13 | driver.useHook( 'dangerously_chainWebpack', config => { 14 | config.plugin( 'define' ) 15 | .tap( args => { 16 | args[ 0 ] = args[ 0 ] || {} 17 | args[ 0 ][ key ] = value 18 | return args 19 | } ) 20 | } ) 21 | } ) 22 | } 23 | -------------------------------------------------------------------------------- /packages/driver-webpack/lib/webpack/dev-server.js: -------------------------------------------------------------------------------- 1 | exports.extendDevServer = function ( serverOptions, context = {} ) { 2 | const { userConfig = {} } = context 3 | const userServerOpts = userConfig.devServer 4 | 5 | if ( !userServerOpts ) { 6 | return 7 | } 8 | 9 | if ( userServerOpts.historyApiFallback ) { 10 | serverOptions.historyApiFallback = userServerOpts.historyApiFallback 11 | } 12 | 13 | if ( userServerOpts.https ) { 14 | serverOptions.https = userServerOpts.https 15 | } 16 | 17 | if ( userServerOpts.headers ) { 18 | serverOptions.headers = userServerOpts.headers 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /packages/driver-webpack/lib/webpack/devtool.js: -------------------------------------------------------------------------------- 1 | exports.extend = function ( config, context ) { 2 | if ( context.env === 'production' ) { 3 | config.devtool( false ) 4 | } else { 5 | config.devtool( 'cheap-module-source-map' ) 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /packages/driver-webpack/lib/webpack/dll.js: -------------------------------------------------------------------------------- 1 | exports.extend = function ( config, context = {} ) { 2 | const { env = '', userConfig = {} } = context 3 | 4 | if ( env === 'production' ) { 5 | return 6 | } 7 | 8 | if ( Boolean( userConfig.dll ) === false ) { 9 | return 10 | } 11 | 12 | const dllLibraries = Array.isArray( userConfig.dll ) ? 13 | userConfig.dll : 14 | [] 15 | 16 | config.plugin( 'dll' ) 17 | .use( require( 'autodll-webpack-plugin' ), [ 18 | { 19 | inject: true, 20 | debug: true, 21 | path: './dll', 22 | filename: '[name].[hash:8].js', 23 | entry: { 24 | vendor: dllLibraries 25 | }, 26 | } 27 | ] ) 28 | } 29 | -------------------------------------------------------------------------------- /packages/driver-webpack/lib/webpack/entry.js: -------------------------------------------------------------------------------- 1 | const localJoin = require( './shared/local-join' ) 2 | 3 | exports.extend = function ( config, context = {} ) { 4 | const { userConfig = {} } = context 5 | const pages = userConfig.pages 6 | const entry = userConfig.entry || 'src/index.js' 7 | 8 | if ( pages ) { 9 | for ( const key of Object.keys( pages ) ) { 10 | const page = pages[ key ] 11 | if ( page ) { 12 | const pageEntry = typeof page === 'string' ? page : page.entry 13 | 14 | if ( typeof pageEntry === 'string' ) { 15 | config.entry( key ).add( localJoin( pageEntry ) ) 16 | } 17 | } 18 | } 19 | } else if ( typeof entry === 'string' ) { 20 | config.entry( 'index' ).add( localJoin( entry ) ) 21 | } 22 | } 23 | 24 | exports.expose = function ( driver ) { 25 | driver.expose( 'entry', { 26 | prepend( injectEntry ) { 27 | driver.useHook( 'dangerously_chainWebpack', config => { 28 | const entryKeys = config.entryPoints.store.keys() 29 | for ( const key of entryKeys ) { 30 | if ( config.entryPoints.has( key ) ) { 31 | config.entry( key ).prepend( injectEntry ) 32 | } 33 | } 34 | } ) 35 | }, 36 | 37 | append( injectEntry ) { 38 | driver.useHook( 'dangerously_chainWebpack', config => { 39 | const entryKeys = config.entryPoints.store.keys() 40 | for ( const key of entryKeys ) { 41 | if ( config.entryPoints.has( key ) ) { 42 | config.entry( key ).append( injectEntry ) 43 | } 44 | } 45 | } ) 46 | } 47 | } ) 48 | } 49 | -------------------------------------------------------------------------------- /packages/driver-webpack/lib/webpack/error-overlay.js: -------------------------------------------------------------------------------- 1 | const errorOverlayMiddleware = require( './overlay/error-overlay-middleware' ) 2 | 3 | exports.extend = function ( config, context = {} ) { 4 | const { env = '' } = context 5 | 6 | if ( env === 'production' ) { 7 | return 8 | } 9 | 10 | const hotClientEntry = require.resolve( './overlay/client' ) 11 | 12 | const entryKeys = config.entryPoints.store.keys() 13 | for ( const key of entryKeys ) { 14 | if ( config.entryPoints.has( key ) ) { 15 | config.entry( key ).prepend( hotClientEntry ) 16 | } 17 | } 18 | } 19 | 20 | exports.extendDevServer = function ( serverOptions, context = {} ) { 21 | const { env = '' } = context 22 | 23 | if ( env === 'production' ) { 24 | return 25 | } 26 | 27 | serverOptions.transportMode = 'ws' 28 | serverOptions.injectClient = false 29 | serverOptions.overlay = false 30 | 31 | const oldBefore = serverOptions.before 32 | 33 | serverOptions.before = function ( app, server, compiler ) { 34 | if ( oldBefore ) { 35 | oldBefore( app, server, compiler ) 36 | } 37 | 38 | app.use( errorOverlayMiddleware() ) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /packages/driver-webpack/lib/webpack/error/transformer-module-not-found.js: -------------------------------------------------------------------------------- 1 | const TYPE = 'module-not-found' 2 | 3 | function isModuleNotFoundError( e ) { 4 | const webpackError = e.webpackError || {} 5 | return webpackError.dependencies && 6 | webpackError.dependencies.length > 0 && 7 | ( e.name === 'ModuleNotFoundError' || e.name === 'Module not found' ) && 8 | e.message.indexOf( 'Module not found' ) === 0 9 | } 10 | 11 | function transform( error ) { 12 | const webpackError = error.webpackError 13 | if ( isModuleNotFoundError( error ) ) { 14 | const module = webpackError.dependencies[ 0 ].request 15 | return Object.assign( {}, error, { 16 | message: `Module not found ${ module }`, 17 | type: TYPE, 18 | severity: 900, 19 | module: module || extractModuleName( webpackError.message ), 20 | name: 'Module not found' 21 | } ) 22 | } 23 | 24 | return error 25 | } 26 | 27 | const re = /Can't resolve '([^']*)'/ 28 | 29 | function extractModuleName( message = '' ) { 30 | const matches = message.match( re ) 31 | 32 | if ( matches && matches[ 1 ] ) { 33 | return matches[ 1 ] 34 | } 35 | } 36 | 37 | module.exports = transform 38 | -------------------------------------------------------------------------------- /packages/driver-webpack/lib/webpack/eslint.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nut-project/nut/672e123a975dc02ffc12a5bbad31a2c5a49fc776/packages/driver-webpack/lib/webpack/eslint.js -------------------------------------------------------------------------------- /packages/driver-webpack/lib/webpack/fast.js: -------------------------------------------------------------------------------- 1 | exports.extend = function ( config, context ) { 2 | if ( context.userConfig.fast === true ) { 3 | config.output.pathinfo( false ) 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/driver-webpack/lib/webpack/filename.js: -------------------------------------------------------------------------------- 1 | exports.extend = function ( config, context = {} ) { 2 | if ( context.env === 'production' ) { 3 | config.output.filename( '[name].[contenthash:8].js' ) 4 | config.output.chunkFilename( '[name].[contenthash:8].js' ) 5 | } else { 6 | // https://survivejs.com/webpack/optimizing/adding-hashes-to-filenames/#placeholders 7 | // also create-react-app doesn't use hash during development 8 | config.output.filename( '[name].js' ) 9 | config.output.chunkFilename( '[name].js' ) 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /packages/driver-webpack/lib/webpack/font.js: -------------------------------------------------------------------------------- 1 | exports.extend = function ( config ) { 2 | config.module 3 | .rule( 'font' ) 4 | .test( /\.(ttf|eot|woff|woff2|svg)(\?t=\d+)?$/i ) 5 | .use( 'url' ) 6 | .loader( require.resolve( 'url-loader' ) ) 7 | .options( { 8 | fallback: require.resolve( 'file-loader' ), 9 | limit: 8192, 10 | name: `static/fonts/[name].[hash:16].[ext]` 11 | } ) 12 | } 13 | -------------------------------------------------------------------------------- /packages/driver-webpack/lib/webpack/friendly-error.js: -------------------------------------------------------------------------------- 1 | const FriendlyErrorsPlugin = require( './plugins/FriendlyErrorPlugin' ) 2 | 3 | exports.extend = function ( config ) { 4 | config 5 | .plugin( 'friendly-error' ) 6 | .use( FriendlyErrorsPlugin ) 7 | } 8 | 9 | exports.extendDevServer = function ( serverOptions = {} ) { 10 | serverOptions.quiet = true 11 | } 12 | -------------------------------------------------------------------------------- /packages/driver-webpack/lib/webpack/hot.js: -------------------------------------------------------------------------------- 1 | const { webpack } = require( '@nut-project/webpack' ) 2 | 3 | exports.extend = function ( config, context = {} ) { 4 | const { env = '' } = context 5 | 6 | if ( env === 'production' ) { 7 | return 8 | } 9 | 10 | config.plugin( 'hmr' ) 11 | .use( webpack.HotModuleReplacementPlugin, [] ) 12 | } 13 | 14 | exports.extendDevServer = function ( serverOptions, context = {} ) { 15 | const { env = '' } = context 16 | 17 | if ( env === 'production' ) { 18 | return 19 | } 20 | 21 | serverOptions.hot = true 22 | } 23 | -------------------------------------------------------------------------------- /packages/driver-webpack/lib/webpack/index.js: -------------------------------------------------------------------------------- 1 | const abilities = [ 2 | require( './public-path' ), 3 | require( './filename' ), 4 | require( './entry' ), 5 | // error-overlay should be after entry 6 | require( './error-overlay' ), 7 | require( './babel' ), 8 | require( './css' ), 9 | require( './html' ), 10 | require( './media' ), 11 | require( './font' ), 12 | require( './copy' ), 13 | require( './clean' ), 14 | require( './analyze' ), 15 | require( './mode' ), 16 | require( './minimizer' ), 17 | require( './minimize' ), 18 | require( './progress' ), 19 | require( './vue' ), 20 | require( './define' ), 21 | require( './resolve' ), 22 | require( './friendly-error' ), 23 | require( './performance' ), 24 | require( './dev-server' ), 25 | require( './missing-node-modules' ), 26 | require( './hot' ), 27 | require( './outdir' ), 28 | 29 | // produce very little effect 30 | // require( './dll' ), 31 | ] 32 | 33 | exports.extendWebpack = function ( config, context = {} ) { 34 | abilities.forEach( ability => { 35 | if ( ability.extend ) { 36 | ability.extend( config, context ) 37 | } 38 | } ) 39 | } 40 | 41 | exports.exposeWebpack = function ( driver, context = {} ) { 42 | abilities.forEach( ability => { 43 | if ( ability.expose ) { 44 | ability.expose( driver, context ) 45 | } 46 | } ) 47 | } 48 | 49 | exports.extendDevServer = function ( serverOptions, context = {} ) { 50 | abilities.forEach( ability => { 51 | if ( ability.extendDevServer ) { 52 | ability.extendDevServer( serverOptions, context ) 53 | } 54 | } ) 55 | } 56 | -------------------------------------------------------------------------------- /packages/driver-webpack/lib/webpack/media.js: -------------------------------------------------------------------------------- 1 | exports.extend = function ( config ) { 2 | config.module 3 | .rule( 'image' ) 4 | .test( /\.(png|jpg|jpeg|gif)$/i ) 5 | .use( 'url' ) 6 | .loader( require.resolve( 'url-loader' ) ) 7 | .options( { 8 | fallback: require.resolve( 'file-loader' ), 9 | limit: 8192, 10 | name: `static/img/[name].[hash:16].[ext]` 11 | } ) 12 | 13 | config.module 14 | .rule( 'media' ) 15 | .test( /\.(mp4|webm|ogg|mp3|wav|flac|aac)$/i ) 16 | .use( 'url' ) 17 | .loader( require.resolve( 'url-loader' ) ) 18 | .options( { 19 | fallback: require.resolve( 'file-loader' ), 20 | limit: 8192, 21 | name: `./static/media/[name].[hash:16].[ext]` 22 | } ) 23 | } 24 | -------------------------------------------------------------------------------- /packages/driver-webpack/lib/webpack/minimize.js: -------------------------------------------------------------------------------- 1 | exports.extend = function ( config, context = {} ) { 2 | const { userConfig = {} } = context 3 | if ( typeof userConfig.minimize !== 'undefined' ) { 4 | config.optimization.minimize( Boolean( userConfig.minimize ) ) 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /packages/driver-webpack/lib/webpack/missing-node-modules.js: -------------------------------------------------------------------------------- 1 | const path = require( 'path' ) 2 | const WatchMissingNodeModulesPlugin = require( './plugins/WatchMissingNodeModulesPlugin' ) 3 | 4 | exports.extend = function ( config ) { 5 | config.plugin( 'watch-missing-node-modules' ) 6 | .use( WatchMissingNodeModulesPlugin, [ 7 | path.join( process.cwd(), 'node_modules' ) 8 | ] ) 9 | } 10 | -------------------------------------------------------------------------------- /packages/driver-webpack/lib/webpack/mode.js: -------------------------------------------------------------------------------- 1 | exports.extend = function ( config, context ) { 2 | if ( context.env === 'production' ) { 3 | config.mode( 'production' ) 4 | } else { 5 | config.mode( 'development' ) 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /packages/driver-webpack/lib/webpack/outdir.js: -------------------------------------------------------------------------------- 1 | const path = require( 'path' ) 2 | 3 | exports.extend = function ( config, context = {} ) { 4 | const { userConfig = {} } = context 5 | 6 | const outdir = userConfig.output && userConfig.output.path 7 | if ( outdir ) { 8 | config.output.path( outdir ) 9 | } else { 10 | config.output.path( path.join( process.cwd(), 'dist' ) ) 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /packages/driver-webpack/lib/webpack/overlay/error-overlay-middleware.js: -------------------------------------------------------------------------------- 1 | /** 2 | * from: create-react-app 3 | * Copyright (c) 2015-present, Facebook, Inc. 4 | * 5 | * This source code is licensed under the MIT license found in the 6 | * LICENSE file in the root directory of this source tree. 7 | */ 8 | 'use strict'; 9 | 10 | const launchEditor = require('./launch-editor'); 11 | const launchEditorEndpoint = require('./launch-editor-endpoint'); 12 | 13 | module.exports = function createLaunchEditorMiddleware() { 14 | return function launchEditorMiddleware(req, res, next) { 15 | if (req.url.startsWith(launchEditorEndpoint)) { 16 | const lineNumber = parseInt(req.query.lineNumber, 10) || 1; 17 | const colNumber = parseInt(req.query.colNumber, 10) || 1; 18 | launchEditor(req.query.fileName, lineNumber, colNumber); 19 | res.end(); 20 | } else { 21 | next(); 22 | } 23 | }; 24 | }; 25 | -------------------------------------------------------------------------------- /packages/driver-webpack/lib/webpack/overlay/launch-editor-endpoint.js: -------------------------------------------------------------------------------- 1 | /** 2 | * from: create-react-app 3 | * Copyright (c) 2015-present, Facebook, Inc. 4 | * 5 | * This source code is licensed under the MIT license found in the 6 | * LICENSE file in the root directory of this source tree. 7 | */ 8 | 'use strict'; 9 | 10 | // TODO: we might want to make this injectable to support DEV-time non-root URLs. 11 | module.exports = '/__open-stack-frame-in-editor'; 12 | -------------------------------------------------------------------------------- /packages/driver-webpack/lib/webpack/performance.js: -------------------------------------------------------------------------------- 1 | exports.extend = function ( config, context ) { 2 | // disable performance hints in non-production mode 3 | if ( context.env !== 'production' ) { 4 | config.performance.hints( false ) 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /packages/driver-webpack/lib/webpack/plugins/FriendlyErrorPlugin.js: -------------------------------------------------------------------------------- 1 | const FriendlyErrorsWebpackPlugin = require( 'friendly-errors-webpack-plugin' ) 2 | const output = require( 'friendly-errors-webpack-plugin/src/output' ) 3 | 4 | const ID = `FriendlyErrorsPlugin` 5 | 6 | class FriendlyErrorsPlugin { 7 | apply( compiler ) { 8 | const friendlyError = new FriendlyErrorsWebpackPlugin( { 9 | clearConsole: false, 10 | additionalTransformers: [ 11 | require( '../error/transformer-module-not-found' ), 12 | ] 13 | } ) 14 | 15 | friendlyError.apply( compiler ) 16 | 17 | compiler.hooks.failed.tap( ID, error => { 18 | friendlyError.clearConsole() 19 | output.title( 'error', 'ERROR', `Failed to compile with 1 errors` ) 20 | console.log( error.stack || error.message ) 21 | } ) 22 | } 23 | } 24 | 25 | module.exports = FriendlyErrorsPlugin 26 | -------------------------------------------------------------------------------- /packages/driver-webpack/lib/webpack/plugins/HtmlCheerioPlugin.js: -------------------------------------------------------------------------------- 1 | const HtmlWebpackPlugin = require( 'html-webpack-plugin' ) 2 | const cheerio = require( 'cheerio' ) 3 | 4 | class HtmlCheerioPlugin { 5 | constructor( callbacks ) { 6 | this.callbacks = callbacks || [] 7 | } 8 | 9 | apply( compiler ) { 10 | const process = async data => { 11 | const callbacks = this.callbacks || [] 12 | 13 | await callbacks.reduce( async ( last, callback ) => { 14 | await last 15 | const $ = cheerio.load( data.html, { 16 | decodeEntities: false, 17 | } ) 18 | await callback( $ ) 19 | data.html = $.html() 20 | }, Promise.resolve() ) 21 | 22 | return data 23 | } 24 | 25 | compiler.hooks.compilation.tap( 'HtmlCheerioPlugin', compilation => { 26 | if ( HtmlWebpackPlugin.getHooks ) { 27 | // html-webpack-plugin@4 28 | HtmlWebpackPlugin 29 | .getHooks( compilation ) 30 | .beforeEmit 31 | .tapPromise( 32 | 'HtmlCheerioPlugin', 33 | process 34 | ) 35 | } else if ( compilation.hooks.htmlWebpackPluginAfterHtmlProcessing ) { 36 | // html-webpack-plugin@3 37 | compilation 38 | .hooks 39 | .htmlWebpackPluginAfterHtmlProcessing 40 | .tapPromise( 41 | 'HtmlCheerioPlugin', 42 | process 43 | ) 44 | } 45 | } ) 46 | } 47 | } 48 | 49 | module.exports = HtmlCheerioPlugin 50 | -------------------------------------------------------------------------------- /packages/driver-webpack/lib/webpack/plugins/WatchMissingNodeModulesPlugin.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | // This Webpack plugin ensures `npm install ` forces a project rebuild. 9 | // We’re not sure why this isn't Webpack's default behavior. 10 | // See https://github.com/facebook/create-react-app/issues/186. 11 | 12 | 'use strict'; 13 | 14 | class WatchMissingNodeModulesPlugin { 15 | constructor(nodeModulesPath) { 16 | this.nodeModulesPath = nodeModulesPath; 17 | } 18 | 19 | apply(compiler) { 20 | compiler.hooks.emit.tap('WatchMissingNodeModulesPlugin', compilation => { 21 | var missingDeps = Array.from(compilation.missingDependencies); 22 | var nodeModulesPath = this.nodeModulesPath; 23 | 24 | // If any missing files are expected to appear in node_modules... 25 | if (missingDeps.some(file => file.includes(nodeModulesPath))) { 26 | // ...tell webpack to watch node_modules recursively until they appear. 27 | compilation.contextDependencies.add(nodeModulesPath); 28 | } 29 | }); 30 | } 31 | } 32 | 33 | module.exports = WatchMissingNodeModulesPlugin; 34 | -------------------------------------------------------------------------------- /packages/driver-webpack/lib/webpack/progress.js: -------------------------------------------------------------------------------- 1 | const WebpackBar = require( 'webpackbar' ) 2 | 3 | exports.extend = function ( config, context = {} ) { 4 | // https://webpack.js.org/guides/build-performance/#progress-plugin 5 | // so we need to disable by default 6 | const { cliOptions = {} } = context 7 | 8 | if ( !cliOptions.progress && !cliOptions.profile ) { 9 | return 10 | } 11 | 12 | const options = { 13 | name: 'client' 14 | } 15 | 16 | if ( context.cliOptions.profile ) { 17 | options.profile = true 18 | options.reporters = [ 'fancy', 'profile' ] 19 | } 20 | 21 | config 22 | .plugin( 'webpackbar' ) 23 | .use( WebpackBar, [ options ] ) 24 | } 25 | -------------------------------------------------------------------------------- /packages/driver-webpack/lib/webpack/public-path.js: -------------------------------------------------------------------------------- 1 | exports.extend = function ( config, context = {} ) { 2 | const { userConfig = {} } = context 3 | const output = userConfig.output 4 | 5 | if ( output && output.publicPath ) { 6 | config.output.publicPath( output.publicPath ) 7 | } else { 8 | config.output.publicPath( '/' ) 9 | } 10 | } 11 | 12 | exports.expose = function ( driver ) { 13 | driver.expose( 'publicPath', pp => { 14 | driver.useHook( 'dangerously_chainWebpack', config => { 15 | config.output.publicPath( pp ) 16 | } ) 17 | } ) 18 | } 19 | -------------------------------------------------------------------------------- /packages/driver-webpack/lib/webpack/resolve.js: -------------------------------------------------------------------------------- 1 | const path = require( 'path' ) 2 | 3 | exports.extend = function ( config, context = {} ) { 4 | const { userConfig = {} } = context 5 | 6 | // extensions 7 | config.resolve.extensions 8 | .merge( [ 9 | '.js', '.json', '.jsx', '.ts', '.tsx', '.wasm', '.mjs', 10 | '.css', '.less', '.scss', '.sass', '.mcss', '.styl', '.stylus', 11 | ] ) 12 | 13 | // alias 14 | const alias = userConfig.alias || {} 15 | for ( const key of Object.keys( alias ) ) { 16 | config.resolve.alias.set( key, alias[ key ] ) 17 | } 18 | 19 | // modules and loaders 20 | const root = path.join( __dirname, '../../' ) 21 | 22 | config.resolve.modules 23 | .add( 'node_modules' ) // use closest node_modules first 24 | .add( path.join( process.cwd(), 'node_modules' ) ) 25 | .add( path.join( root, 'node_modules' ) ) 26 | .add( path.join( root, '../../' ) ) 27 | 28 | config.resolveLoader.modules 29 | .add( 'node_modules' ) 30 | .add( path.join( process.cwd(), 'node_modules' ) ) 31 | .add( path.join( root, 'node_modules' ) ) 32 | .add( path.join( root, '../../' ) ) 33 | } 34 | -------------------------------------------------------------------------------- /packages/driver-webpack/lib/webpack/shared/apply-css-rule.js: -------------------------------------------------------------------------------- 1 | const MiniCssExtractPlugin = require( 'mini-css-extract-plugin' ) 2 | const { config } = require( '@nut-project/dev-utils' ) 3 | 4 | const hasPostCSSConfig = Boolean( config( 'postcss' ).loadSync() ) 5 | 6 | function applyCSSRule( webpackConfig, lang, test, loader, options, extract ) { 7 | const rule = webpackConfig.module 8 | .rule( lang ) 9 | .test( test ) 10 | 11 | const cssModulesRule = rule.oneOf( `${ lang }-modules` ) 12 | const cssRule = rule.oneOf( lang ) 13 | 14 | // for *.module.* 15 | cssModulesRule.test( /\.module\.\w+$/ ) 16 | 17 | apply( cssModulesRule, lang, loader, options, extract, true ) 18 | apply( cssRule, lang, loader, options, extract, false ) 19 | } 20 | 21 | function apply( rule, lang, loader, options, extract, modules ) { 22 | if ( extract ) { 23 | rule.use( 'mini-css-extract' ) 24 | .loader( MiniCssExtractPlugin.loader ) 25 | .options( { 26 | hmr: false, 27 | } ) 28 | } else { 29 | rule.use( 'style' ) 30 | .loader( require.resolve( 'style-loader' ) ) 31 | } 32 | 33 | rule.use( 'css' ) 34 | .loader( require.resolve( 'css-loader' ) ) 35 | .options( { 36 | modules: modules ? { 37 | localIdentName: '[local]___[hash:base64:5]', 38 | } : false, 39 | importLoaders: loader ? 2 : 1, 40 | } ) 41 | 42 | const postcssOptions = { 43 | ident: 'postcss', 44 | } 45 | 46 | if ( !hasPostCSSConfig ) { 47 | // config default postcss config 48 | // with plugins field set, postcss-loader will not search for config file 49 | postcssOptions.plugins = [ 50 | require( 'postcss-flexbugs-fixes' ), 51 | require( 'postcss-preset-env' )( { 52 | autoprefixer: { 53 | flexbox: 'no-2009', 54 | }, 55 | stage: 3, 56 | } ) 57 | ] 58 | } 59 | 60 | rule.use( 'postcss' ) 61 | .loader( require.resolve( 'postcss-loader' ) ) 62 | .options( postcssOptions ) 63 | 64 | if ( loader ) { 65 | rule.use( lang ) 66 | .loader( require.resolve( loader ) ) 67 | .options( options || {} ) 68 | } 69 | } 70 | exports.applyCSSRule = applyCSSRule 71 | -------------------------------------------------------------------------------- /packages/driver-webpack/lib/webpack/shared/create-include.js: -------------------------------------------------------------------------------- 1 | const memoize = require( 'fast-memoize' ) 2 | 3 | module.exports = function ( transpileModules = [] ) { 4 | return memoize( function ( filepath = '' ) { 5 | filepath = filepath.replace( /\\/g, '/' ) 6 | 7 | // skip transpiling overlay code for development mode 8 | if ( filepath.includes( 'driver-webpack/lib/webpack/overlay' ) ) { 9 | return false 10 | } 11 | 12 | // transpile modules outside node_modules 13 | if ( !filepath.includes( 'node_modules' ) ) { 14 | return true 15 | } 16 | 17 | if ( transpileModules.length > 0 ) { 18 | return transpileModules.some( m => { 19 | if ( typeof m === 'string' ) { 20 | return filepath.includes( `/node_modules/${ m }/` ) || 21 | filepath.includes( `/node_modules/_${ m.replace( /\//g, '_' ) }` ) 22 | } 23 | 24 | if ( m && m.test ) { 25 | return m.test( filepath ) 26 | } 27 | 28 | if ( typeof m === 'function' ) { 29 | return m( filepath ) 30 | } 31 | 32 | return false 33 | } ) 34 | } 35 | 36 | return false 37 | } ) 38 | } 39 | -------------------------------------------------------------------------------- /packages/driver-webpack/lib/webpack/shared/get-cache-config.js: -------------------------------------------------------------------------------- 1 | const fs = require( 'fs' ) 2 | const path = require( 'path' ) 3 | const hash = require( 'hash-sum' ) 4 | const localJoin = require( './local-join' ) 5 | const localResolve = require( './local-resolve' ) 6 | 7 | module.exports = ( id = '', customFactors = {}, configfiles = [] ) => { 8 | const root = path.join( __dirname, '../../../' ) 9 | 10 | const factors = { 11 | customFactors, 12 | env: process.env.NODE_ENV, 13 | self: require( path.join( root, 'package.json' ) ).version, 14 | 'cache-loader': require( 'cache-loader/package.json' ).version, 15 | configfile: readConfig( configfiles || [] ), 16 | lockfile: readConfig( [ 17 | 'package-lock.json', 18 | 'yarn.lock', 19 | ] ) 20 | } 21 | 22 | return { 23 | cacheDirectory: localJoin( `node_modules/.cache/${ id }` ), 24 | cacheIdentifier: hash( factors ) 25 | } 26 | } 27 | 28 | // from vue cli 29 | const read = file => { 30 | const absolutePath = localResolve( file ) 31 | 32 | if ( !absolutePath || !fs.existsSync( absolutePath ) ) { 33 | return 34 | } 35 | 36 | if ( absolutePath.endsWith( '.js' ) ) { 37 | // should evaluate config scripts to reflect environment variable changes 38 | try { 39 | return JSON.stringify( require( absolutePath ) ) 40 | } catch ( e ) { 41 | return fs.readFileSync( absolutePath, 'utf-8' ) 42 | } 43 | } else { 44 | return fs.readFileSync( absolutePath, 'utf-8' ) 45 | } 46 | } 47 | 48 | function readConfig( files = [] ) { 49 | if ( files.length === 0 ) { 50 | return '' 51 | } 52 | 53 | for ( const file of files ) { 54 | const content = read( file ) 55 | if ( content ) { 56 | return content 57 | } 58 | } 59 | 60 | return '' 61 | } 62 | -------------------------------------------------------------------------------- /packages/driver-webpack/lib/webpack/shared/local-join.js: -------------------------------------------------------------------------------- 1 | const path = require( 'path' ) 2 | 3 | module.exports = function ( segment ) { 4 | if ( path.isAbsolute( segment ) ) { 5 | return segment 6 | } 7 | 8 | return path.join( process.cwd(), segment ) 9 | } 10 | -------------------------------------------------------------------------------- /packages/driver-webpack/lib/webpack/shared/local-require.js: -------------------------------------------------------------------------------- 1 | const localResolve = require( './local-resolve' ) 2 | 3 | module.exports = ( id, context ) => { 4 | const resolved = localResolve( id, context ) 5 | 6 | return resolved ? require( resolved ) : null 7 | } 8 | -------------------------------------------------------------------------------- /packages/driver-webpack/lib/webpack/shared/local-resolve.js: -------------------------------------------------------------------------------- 1 | const resolveFrom = require( 'resolve-from' ) 2 | 3 | module.exports = ( id, context = process.cwd() ) => { 4 | return resolveFrom.silent( context, id ) 5 | } 6 | -------------------------------------------------------------------------------- /packages/driver-webpack/lib/webpack/shared/parallel.js: -------------------------------------------------------------------------------- 1 | module.exports = rule => { 2 | rule.use( 'thread' ).loader( require.resolve( 'thread-loader' ) ) 3 | } 4 | -------------------------------------------------------------------------------- /packages/driver-webpack/lib/webpack/shared/resolve.js: -------------------------------------------------------------------------------- 1 | const resolveFrom = require( 'resolve-from' ) 2 | const path = require( 'path' ) 3 | 4 | const root = path.join( __dirname, '../../../' ) 5 | 6 | module.exports = id => { 7 | return resolveFrom.silent( root, id ) 8 | } 9 | -------------------------------------------------------------------------------- /packages/driver-webpack/lib/webpack/template.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | <%= htmlWebpackPlugin.options.title %> 6 | 7 | 8 | 9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /packages/driver-webpack/lib/webpack/typescript.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nut-project/nut/672e123a975dc02ffc12a5bbad31a2c5a49fc776/packages/driver-webpack/lib/webpack/typescript.js -------------------------------------------------------------------------------- /packages/driver-webpack/lib/webpack/vue.js: -------------------------------------------------------------------------------- 1 | const path = require( 'path' ) 2 | const resolveFrom = require( 'resolve-from' ) 3 | const VueLoaderPlugin = require( 'vue-loader/lib/plugin' ) 4 | const localResolve = require( './shared/local-resolve' ) 5 | const getCacheConfig = require( './shared/get-cache-config' ) 6 | 7 | exports.extend = function ( config, context = {} ) { 8 | const { env, userConfig = {} } = context 9 | const cache = env === 'development' && userConfig.cache !== false 10 | 11 | config.resolve.extensions 12 | .merge( [ 13 | '.vue' 14 | ] ) 15 | 16 | const vueOptions = cache ? 17 | getVueCacheConfig() : 18 | {} 19 | 20 | config.module 21 | .rule( 'vue' ) 22 | .test( /\.vue$/i ) 23 | .use( 'vue' ) 24 | .loader( require.resolve( 'vue-loader' ) ) 25 | .options( vueOptions ) 26 | 27 | config 28 | .plugin( 'vue' ) 29 | .use( VueLoaderPlugin ) 30 | } 31 | 32 | // modify from poi 33 | function getVueCacheConfig() { 34 | const vueLoaderPath = path.dirname( require.resolve( 'vue-loader' ) ) 35 | const compilerPkgPath = resolveFrom.silent( 36 | vueLoaderPath, 37 | '@vue/component-compiler-utils/package.json' 38 | ) 39 | const compilerPkg = compilerPkgPath ? require( compilerPkgPath ) : {} 40 | 41 | const templateCompilerPkgPath = localResolve( 42 | 'vue-template-compiler/package.json' 43 | ) 44 | 45 | const templateCompilerPkg = templateCompilerPkgPath ? 46 | require( templateCompilerPkgPath ) : 47 | {} 48 | 49 | return getCacheConfig( 'vue-loader', { 50 | 'vue-loader': require( 'vue-loader/package.json' ).version, 51 | '@vue/component-compiler-utils': compilerPkg.version, 52 | 'vue-template-compiler': templateCompilerPkg.version, 53 | } ) 54 | } 55 | -------------------------------------------------------------------------------- /packages/driver-webpack/plugins/clear-console.js: -------------------------------------------------------------------------------- 1 | const readline = require( 'readline' ) 2 | 3 | class ClearConsoleBeforeRunPlugin { 4 | apply( ctx ) { 5 | const { hook } = ctx.use( 'webpack' ) 6 | hook( 'env', env => { 7 | if ( env === 'development' ) { 8 | hook( 'beforeRun', async () => { 9 | clearConsole() 10 | } ) 11 | } 12 | } ) 13 | } 14 | } 15 | 16 | module.exports = ClearConsoleBeforeRunPlugin 17 | 18 | // from friendly-errors-webpack-plugin 19 | function clearConsole() { 20 | if ( process.stdout.isTTY ) { 21 | const blank = '\n'.repeat( process.stdout.rows ) 22 | console.log( blank ) 23 | readline.cursorTo( process.stdout, 0, 0 ) 24 | readline.clearScreenDown( process.stdout ) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /packages/driver-webpack/plugins/memory-usage.js: -------------------------------------------------------------------------------- 1 | const prettyBytes = require( 'pretty-bytes' ) 2 | const chalk = require( 'chalk' ) 3 | 4 | class MemoryUsagePlugin { 5 | apply( ctx ) { 6 | const { hook } = ctx.use( 'webpack' ) 7 | 8 | hook( 'compilerDone', () => { 9 | const { heapUsed } = process.memoryUsage() 10 | setTimeout( () => { 11 | console.log( chalk.gray( `\n${ prettyBytes( heapUsed ) } Memory Used\n` ) ) 12 | }, 1000 ) 13 | } ) 14 | } 15 | } 16 | 17 | module.exports = MemoryUsagePlugin 18 | -------------------------------------------------------------------------------- /packages/driver-webpack/plugins/raw-html.js: -------------------------------------------------------------------------------- 1 | class RawHTMLPlugin { 2 | apply( ctx ) { 3 | const { hook } = ctx.use( 'webpack' ) 4 | 5 | hook( 'dangerously_chainWebpack', config => { 6 | config.module 7 | .rule( 'html' ) 8 | .test( /\.html$/i ) 9 | .use( 'raw' ) 10 | .loader( require.resolve( 'raw-loader' ) ) 11 | } ) 12 | } 13 | } 14 | 15 | module.exports = RawHTMLPlugin 16 | -------------------------------------------------------------------------------- /packages/driver-webpack/plugins/server-info.js: -------------------------------------------------------------------------------- 1 | const { openBrowser } = require( '@nut-project/dev-utils' ) 2 | const chalk = require( 'chalk' ) 3 | const address = require( 'address' ) 4 | const boxen = require( 'boxen' ) 5 | 6 | class ServerInfoPlugin { 7 | apply( ctx ) { 8 | const { hook } = ctx.use( 'webpack' ) 9 | 10 | let host, port 11 | hook( 'dangerously_serverOptions', ( serverOptions = {} ) => { 12 | host = serverOptions.host 13 | port = serverOptions.port 14 | } ) 15 | 16 | hook( 'stdin', key => { 17 | const ENTER = '\r' 18 | 19 | if ( key === ENTER ) { 20 | if ( host && port ) { 21 | openBrowser( `http://${ host }:${ port }` ) 22 | } 23 | } 24 | } ) 25 | 26 | hook( 'dangerously_serverOptions', ( serverOptions = {} ) => { 27 | const { host, port } = serverOptions 28 | hook( 'afterServe', async () => { 29 | console.log() 30 | console.log( 31 | boxen( 32 | `Your application will run at${ getTips( { host, port } ) }`, 33 | { 34 | padding: 1, 35 | borderColor: 'gray' 36 | } 37 | ) 38 | ) 39 | 40 | console.log() 41 | console.log( chalk.gray( 'Press "Enter" to open in browser' ) ) 42 | console.log() 43 | } ) 44 | } ) 45 | } 46 | } 47 | 48 | module.exports = ServerInfoPlugin 49 | 50 | function getTips( { host, port } ) { 51 | const url = 'http://' + host + ':' + port 52 | const lanIP = address.ip() 53 | const lanUrl = lanIP ? `http://${ lanIP }:${ port }` : '' 54 | 55 | const localTips = `\n\nLocal: ${ chalk.cyan( url ) }` 56 | const lanTips = lanUrl ? `\n\nNetwork: ${ chalk.cyan( lanUrl ) }` : '' 57 | 58 | if ( host === '0.0.0.0' ) { 59 | return localTips + lanTips 60 | } 61 | 62 | return localTips 63 | } 64 | -------------------------------------------------------------------------------- /packages/musubi/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. 5 | 6 | # [1.0.0-alpha.3](https://github.com/nut-project/nut/tree/master/packages/land/compare/@nut-project/musubi@1.0.0-alpha.2...@nut-project/musubi@1.0.0-alpha.3) (2019-12-06) 7 | 8 | **Note:** Version bump only for package @nut-project/musubi 9 | 10 | 11 | 12 | 13 | 14 | ## [0.0.1-alpha.2](https://github.com/nut-project/nut/tree/master/packages/land/compare/@nut-project/musubi@0.0.1-alpha.1...@nut-project/musubi@0.0.1-alpha.2) (2019-10-08) 15 | 16 | **Note:** Version bump only for package @nut-project/musubi 17 | -------------------------------------------------------------------------------- /packages/musubi/lib/index.js: -------------------------------------------------------------------------------- 1 | const Musubi = require( './musubi' ) 2 | const { singleton } = require( './utils' ) 3 | 4 | module.exports = () => singleton( Musubi ) 5 | -------------------------------------------------------------------------------- /packages/musubi/lib/musubi.js: -------------------------------------------------------------------------------- 1 | const cac = require( 'cac' ) 2 | const { utils } = require( '@nut-project/dev-utils' ) 3 | 4 | class Musubi { 5 | constructor() { 6 | this.cli = cac() 7 | this.drivers = {} 8 | this.plugins = {} 9 | } 10 | 11 | // use driver 12 | // name / version / scope / apply 13 | async use( driver ) { 14 | if ( !driver.name || !driver.version || !driver.scope || !driver.apply ) { 15 | return 16 | } 17 | 18 | const scope = driver.scope 19 | 20 | await driver.apply( { 21 | scope, 22 | register: plugin => { 23 | if ( typeof plugin === 'undefined' ) { 24 | return 25 | } 26 | 27 | this.plugins[ scope ] = this.plugins[ scope ] || [] 28 | if ( !this.plugins[ scope ].includes( plugin ) ) { 29 | this.plugins[ scope ].push( plugin ) 30 | } 31 | 32 | this.drivers[ scope ] = this.drivers[ scope ] || [] 33 | if ( !this.drivers[ scope ].includes( driver ) ) { 34 | this.drivers[ scope ].push( driver ) 35 | } 36 | } 37 | } ) 38 | } 39 | 40 | version( version ) { 41 | if ( version ) { 42 | this.cli.version( version ) 43 | } 44 | } 45 | 46 | async apply() { 47 | const argv = process.argv 48 | 49 | // find matched plugins by scope 50 | // e.g. rootCommand subCommand --option 51 | let scope = argv[ 2 ] 52 | let plugins = this.plugins[ scope ] 53 | 54 | // remove scope from argv 55 | if ( plugins ) { 56 | argv.splice( 2, 1 ) 57 | } 58 | 59 | // use plugins from '' 60 | if ( !plugins ) { 61 | scope = '' 62 | plugins = this.plugins[ '' ] || [] 63 | } 64 | 65 | if ( plugins && plugins.length === 0 ) { 66 | console.log( '\nCommand not found\n' ) 67 | } 68 | 69 | const drivers = this.drivers[ scope ] 70 | utils.poweredBy( drivers ) 71 | 72 | const pendings = plugins.map( plugin => plugin( this.cli ) ) 73 | await Promise.all( pendings ) 74 | 75 | this.cli.help() 76 | this.cli.parse( argv ) 77 | } 78 | } 79 | 80 | module.exports = Musubi 81 | -------------------------------------------------------------------------------- /packages/musubi/lib/utils.js: -------------------------------------------------------------------------------- 1 | exports.singleton = ( function () { 2 | const map = new Map() 3 | 4 | return function singleton( FactoryClass ) { 5 | if ( !map.has( FactoryClass ) ) { 6 | map.set( FactoryClass, new FactoryClass() ) 7 | } 8 | 9 | return map.get( FactoryClass ) 10 | } 11 | } )() 12 | -------------------------------------------------------------------------------- /packages/musubi/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@nut-project/musubi", 3 | "version": "1.0.0-alpha.4", 4 | "publishConfig": { 5 | "access": "public" 6 | }, 7 | "description": "pluggable cli framework", 8 | "keywords": [ 9 | "cli", 10 | "pluggable", 11 | "framework" 12 | ], 13 | "main": "lib/index.js", 14 | "files": [ 15 | "lib", 16 | "yarn.lock", 17 | "README.md" 18 | ], 19 | "engines": { 20 | "node": ">=8.9.0" 21 | }, 22 | "repository": "https://github.com/nut-project/nut/tree/master/packages/land", 23 | "homepage": "http://nut.js.org", 24 | "bugs": { 25 | "url": "https://github.com/nut-project/nut/issues/new/choose" 26 | }, 27 | "scripts": {}, 28 | "author": { 29 | "name": "fengzilong", 30 | "email": "fengzilong1992@gmail.com", 31 | "url": "https://github.com/fengzilong" 32 | }, 33 | "license": "MIT", 34 | "dependencies": { 35 | "@nut-project/dev-utils": "^1.0.0-alpha.4", 36 | "cac": "^6.5.3" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /packages/presets-alpha/lib/index.js: -------------------------------------------------------------------------------- 1 | module.exports = [ 2 | { 3 | cli: require.resolve( '@nut-project/cli-pages' ), 4 | drivers: [ 5 | require.resolve( '@nut-project/driver-webpack' ), 6 | ], 7 | plugins: { 8 | clearConsole: require.resolve( '@nut-project/driver-webpack/plugins/clear-console' ), 9 | memoryUsage: require.resolve( '@nut-project/driver-webpack/plugins/memory-usage' ), 10 | serverInfo: require.resolve( '@nut-project/driver-webpack/plugins/server-info' ), 11 | } 12 | } 13 | ] 14 | -------------------------------------------------------------------------------- /packages/presets-alpha/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@nut-project/presets-alpha", 3 | "version": "1.0.0-alpha.20", 4 | "publishConfig": { 5 | "access": "public" 6 | }, 7 | "description": "presets alpha 初号机", 8 | "keywords": [ 9 | "webpack" 10 | ], 11 | "main": "lib/index.js", 12 | "files": [ 13 | "lib", 14 | "yarn.lock", 15 | "README.md" 16 | ], 17 | "engines": { 18 | "node": ">=8.9.0" 19 | }, 20 | "repository": "https://github.com/nut-project/nut/tree/master/packages/presets-alpha", 21 | "homepage": "http://nut.js.org", 22 | "bugs": { 23 | "url": "https://github.com/nut-project/nut/issues/new/choose" 24 | }, 25 | "scripts": {}, 26 | "author": { 27 | "name": "fengzilong", 28 | "email": "fengzilong1992@gmail.com", 29 | "url": "https://github.com/fengzilong" 30 | }, 31 | "license": "MIT", 32 | "dependencies": { 33 | "@nut-project/cli-pages": "^1.0.0-alpha.8", 34 | "@nut-project/driver-webpack": "^1.0.0-alpha.21" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /packages/webpack/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. 5 | 6 | # [1.0.0-alpha.4](https://github.com/nut-project/nut/tree/master/packages/webpack/compare/@nut-project/webpack@1.0.0-alpha.3...@nut-project/webpack@1.0.0-alpha.4) (2020-02-29) 7 | 8 | 9 | ### Features 10 | 11 | * add modern build plugin ([#83](https://github.com/nut-project/nut/tree/master/packages/webpack/issues/83)) ([c3539c5](https://github.com/nut-project/nut/tree/master/packages/webpack/commit/c3539c533ba293a48b62d7255c49331975396e36)) 12 | 13 | 14 | 15 | 16 | 17 | # [1.0.0-alpha.3](https://github.com/nut-project/nut/tree/master/packages/webpack/compare/@nut-project/webpack@1.0.0-alpha.2...@nut-project/webpack@1.0.0-alpha.3) (2019-12-06) 18 | 19 | **Note:** Version bump only for package @nut-project/webpack 20 | -------------------------------------------------------------------------------- /packages/webpack/lib/build.js: -------------------------------------------------------------------------------- 1 | module.exports = function build( compiler ) { 2 | return new Promise( ( resolve, reject ) => { 3 | compiler.run( ( err, stats ) => { 4 | if ( err ) { 5 | return reject( err ) 6 | } 7 | 8 | resolve( stats ) 9 | } ) 10 | } ) 11 | } 12 | -------------------------------------------------------------------------------- /packages/webpack/lib/chain.js: -------------------------------------------------------------------------------- 1 | const Config = require( 'webpack-chain' ) 2 | 3 | module.exports = function () { 4 | return new Config() 5 | } 6 | -------------------------------------------------------------------------------- /packages/webpack/lib/helpers.js: -------------------------------------------------------------------------------- 1 | const path = require( 'path' ) 2 | 3 | function webpackResolve( request ) { 4 | const root = path.dirname( require.resolve( 'webpack/package.json' ) ) 5 | return path.join( root, request ) 6 | } 7 | 8 | function webpackRequire( request ) { 9 | return require( webpackResolve( request ) ) 10 | } 11 | 12 | exports.webpackResolve = webpackResolve 13 | exports.webpackRequire = webpackRequire 14 | -------------------------------------------------------------------------------- /packages/webpack/lib/hot.js: -------------------------------------------------------------------------------- 1 | const WebpackDevServer = require( 'webpack-dev-server' ) 2 | 3 | module.exports = function ( config, serverOptions ) { 4 | return WebpackDevServer.addDevServerEntrypoints( config, serverOptions ) 5 | } 6 | -------------------------------------------------------------------------------- /packages/webpack/lib/index.js: -------------------------------------------------------------------------------- 1 | const helpers = require( './helpers' ) 2 | 3 | exports.chain = require( './chain' ) 4 | exports.serve = require( './serve' ) 5 | exports.build = require( './build' ) 6 | exports.hot = require( './hot' ) 7 | exports.WebpackDevServer = require( 'webpack-dev-server' ) 8 | exports.webpack = require( 'webpack' ) 9 | exports.webpackResolve = helpers.webpackResolve 10 | exports.webpackRequire = helpers.webpackRequire 11 | -------------------------------------------------------------------------------- /packages/webpack/lib/serve.js: -------------------------------------------------------------------------------- 1 | const WebpackDevServer = require( 'webpack-dev-server' ) 2 | 3 | module.exports = function serve( compiler = {}, serverConfig = {}, callback ) { 4 | const server = new WebpackDevServer( compiler, serverConfig ) 5 | 6 | const { host, port } = serverConfig 7 | 8 | server.listen( 9 | port, 10 | host, 11 | callback 12 | ) 13 | 14 | return server 15 | } 16 | -------------------------------------------------------------------------------- /packages/webpack/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@nut-project/webpack", 3 | "version": "1.0.0-alpha.5", 4 | "publishConfig": { 5 | "access": "public" 6 | }, 7 | "description": "webpack api for nut", 8 | "keywords": [ 9 | "webpack" 10 | ], 11 | "main": "lib/index.js", 12 | "files": [ 13 | "lib", 14 | "yarn.lock", 15 | "README.md" 16 | ], 17 | "engines": { 18 | "node": ">=8.9.0" 19 | }, 20 | "repository": "https://github.com/nut-project/nut/tree/master/packages/webpack", 21 | "homepage": "http://nut.js.org", 22 | "bugs": { 23 | "url": "https://github.com/nut-project/nut/issues/new/choose" 24 | }, 25 | "scripts": {}, 26 | "author": { 27 | "name": "fengzilong", 28 | "email": "fengzilong1992@gmail.com", 29 | "url": "https://github.com/fengzilong" 30 | }, 31 | "license": "MIT", 32 | "dependencies": { 33 | "webpack": "^4.41.0", 34 | "webpack-chain": "^6.0.0", 35 | "webpack-dev-server": "^3.8.1" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /plugins/modern-build/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. 5 | 6 | # 1.0.0-alpha.1 (2020-02-29) 7 | 8 | 9 | ### Features 10 | 11 | * add modern build plugin ([#83](https://github.com/nut-project/nut/tree/master/plugins/modern-build/issues/83)) ([c3539c5](https://github.com/nut-project/nut/tree/master/plugins/modern-build/commit/c3539c533ba293a48b62d7255c49331975396e36)) 12 | -------------------------------------------------------------------------------- /plugins/modern-build/lib/index.js: -------------------------------------------------------------------------------- 1 | const copy = require( 'fast-copy' ) 2 | const ModernBuildWebpackPlugin = require( './plugin' ) 3 | 4 | class ModernBuildPlugin { 5 | constructor( options = {} ) { 6 | this._options = options 7 | } 8 | 9 | apply( ctx ) { 10 | const { api, hook } = ctx.use( 'webpack' ) 11 | 12 | hook( 'env', env => { 13 | if ( env !== 'production' ) { 14 | return 15 | } 16 | 17 | hook( 'dangerously_chainWebpack', config => { 18 | config.module.rule( 'js' ) 19 | .use( 'babel' ) 20 | .tap( options => { 21 | options.isModern = true 22 | return options 23 | } ) 24 | 25 | config.optimization.runtimeChunk( false ) 26 | 27 | let legacyTerserPluginOptions = {} 28 | config.optimization.minimizer( 'js' ) 29 | .tap( ( [ options = {} ] ) => { 30 | legacyTerserPluginOptions = copy( options ) 31 | options.terserOptions.module = true 32 | options.terserOptions.ecma = 2017 33 | return [ options ] 34 | } ) 35 | 36 | const options = { 37 | api: { 38 | webpackRequire: api.dangerously_webpackRequire, 39 | driverRequire: api.dangerously_require 40 | }, 41 | legacyTerserPluginOptions, 42 | } 43 | 44 | config.plugin( 'modern-build' ) 45 | .use( ModernBuildWebpackPlugin, [ options ] ) 46 | } ) 47 | } ) 48 | } 49 | } 50 | 51 | module.exports = ModernBuildPlugin 52 | -------------------------------------------------------------------------------- /plugins/modern-build/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@nut-plugins/modern-build", 3 | "version": "1.0.0-alpha.2", 4 | "publishConfig": { 5 | "access": "public" 6 | }, 7 | "description": "modern build plugin for nut", 8 | "keywords": [ 9 | "nut", 10 | "vue", 11 | "modern build", 12 | "plugin" 13 | ], 14 | "main": "lib/index.js", 15 | "files": [ 16 | "lib" 17 | ], 18 | "engines": { 19 | "node": ">=8.9.0" 20 | }, 21 | "repository": "https://github.com/nut-project/nut/tree/master/plugins/modern-build", 22 | "homepage": "http://nut.js.org", 23 | "bugs": { 24 | "url": "https://github.com/nut-project/nut/issues/new/choose" 25 | }, 26 | "scripts": {}, 27 | "author": { 28 | "name": "fengzilong", 29 | "email": "fengzilong1992@gmail.com", 30 | "url": "https://github.com/fengzilong" 31 | }, 32 | "license": "MIT", 33 | "dependencies": { 34 | "fast-copy": "^2.0.4" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /plugins/pages/layout-kaola/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. 5 | 6 | # [1.0.0-alpha.4](https://github.com/nut-project/nut/tree/master/plugins/pages/layout-kaola/compare/@nut-plugins/pages-layout-kaola@1.0.0-alpha.3...@nut-plugins/pages-layout-kaola@1.0.0-alpha.4) (2020-02-29) 7 | 8 | **Note:** Version bump only for package @nut-plugins/pages-layout-kaola 9 | 10 | 11 | 12 | 13 | 14 | # [1.0.0-alpha.3](https://github.com/nut-project/nut/tree/master/plugins/pages/layout-kaola/compare/@nut-plugins/pages-layout-kaola@1.0.0-alpha.2...@nut-plugins/pages-layout-kaola@1.0.0-alpha.3) (2019-12-06) 15 | 16 | **Note:** Version bump only for package @nut-plugins/pages-layout-kaola 17 | -------------------------------------------------------------------------------- /plugins/pages/layout-kaola/lib/index.js: -------------------------------------------------------------------------------- 1 | const path = require( 'path' ) 2 | 3 | exports.name = 'layout-kaola' 4 | exports.apply = api => { 5 | api.addRuntimeModule( { 6 | file: path.join( __dirname, './runtime.js' ), 7 | } ) 8 | } 9 | -------------------------------------------------------------------------------- /plugins/pages/layout-kaola/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@nut-plugins/pages-layout-kaola", 3 | "version": "1.0.0-alpha.5", 4 | "publishConfig": { 5 | "access": "public" 6 | }, 7 | "description": "pages-layout-kaola", 8 | "keywords": [ 9 | "nut", 10 | "pages", 11 | "plugin" 12 | ], 13 | "main": "lib/index.js", 14 | "files": [ 15 | "lib" 16 | ], 17 | "engines": { 18 | "node": ">=8.9.0" 19 | }, 20 | "repository": "https://github.com/nut-project/nut/tree/master/plugins/pages/layout-kaola", 21 | "homepage": "http://nut.js.org", 22 | "bugs": { 23 | "url": "https://github.com/nut-project/nut/issues/new/choose" 24 | }, 25 | "scripts": {}, 26 | "author": { 27 | "name": "fengzilong", 28 | "email": "fengzilong1992@gmail.com", 29 | "url": "https://github.com/fengzilong" 30 | }, 31 | "license": "MIT", 32 | "dependencies": { 33 | "chalk": "^2.4.2", 34 | "cosmiconfig": "^5.2.1", 35 | "globby": "^10.0.1", 36 | "gradient-string": "^1.2.0", 37 | "signale": "^1.4.0" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /plugins/pages/layout-now/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. 5 | 6 | # [1.0.0-alpha.4](https://github.com/nut-project/nut/tree/master/plugins/pages/layout-now/compare/@nut-plugins/pages-layout-now@1.0.0-alpha.3...@nut-plugins/pages-layout-now@1.0.0-alpha.4) (2020-02-29) 7 | 8 | **Note:** Version bump only for package @nut-plugins/pages-layout-now 9 | 10 | 11 | 12 | 13 | 14 | # [1.0.0-alpha.3](https://github.com/nut-project/nut/tree/master/plugins/pages/layout-now/compare/@nut-plugins/pages-layout-now@1.0.0-alpha.2...@nut-plugins/pages-layout-now@1.0.0-alpha.3) (2019-12-06) 15 | 16 | **Note:** Version bump only for package @nut-plugins/pages-layout-now 17 | -------------------------------------------------------------------------------- /plugins/pages/layout-now/lib/headroom.module.less: -------------------------------------------------------------------------------- 1 | .transition { 2 | transition: transform .2s ease; 3 | } 4 | 5 | .initial { 6 | transform: translateY(0); 7 | } 8 | 9 | .pinned { 10 | transform: translateY(0); 11 | } 12 | 13 | .unpinned { 14 | transform: translateY(-100%); 15 | } 16 | 17 | .top, .bottom, .notTop, .notBottom { 18 | width: 100%; 19 | } 20 | -------------------------------------------------------------------------------- /plugins/pages/layout-now/lib/index.js: -------------------------------------------------------------------------------- 1 | const path = require( 'path' ) 2 | 3 | exports.name = 'layout-now' 4 | exports.apply = ( api, options ) => { 5 | api.addRuntimeModule( { 6 | file: path.join( __dirname, 'runtime.js' ), 7 | options, 8 | } ) 9 | } 10 | -------------------------------------------------------------------------------- /plugins/pages/layout-now/lib/nprogress.css: -------------------------------------------------------------------------------- 1 | /* Make clicks pass-through */ 2 | #nprogress { 3 | pointer-events: none; 4 | } 5 | 6 | #nprogress .bar { 7 | background: #000; 8 | 9 | position: fixed; 10 | z-index: 1031; 11 | top: 0; 12 | left: 0; 13 | 14 | width: 100%; 15 | height: 1px; 16 | } 17 | 18 | /* Fancy blur effect */ 19 | #nprogress .peg { 20 | display: block; 21 | position: absolute; 22 | right: 0px; 23 | width: 100px; 24 | height: 100%; 25 | box-shadow: 0 0 10px #000, 0 0 5px #000; 26 | opacity: 1.0; 27 | 28 | -webkit-transform: rotate(3deg) translate(0px, -4px); 29 | -ms-transform: rotate(3deg) translate(0px, -4px); 30 | transform: rotate(3deg) translate(0px, -4px); 31 | } 32 | 33 | /* Remove these to get rid of the spinner */ 34 | #nprogress .spinner { 35 | display: block; 36 | position: fixed; 37 | z-index: 1031; 38 | top: 15px; 39 | right: 15px; 40 | } 41 | 42 | #nprogress .spinner-icon { 43 | width: 18px; 44 | height: 18px; 45 | box-sizing: border-box; 46 | 47 | border: solid 2px transparent; 48 | border-top-color: #000; 49 | border-left-color: #000; 50 | border-radius: 50%; 51 | 52 | -webkit-animation: nprogress-spinner 400ms linear infinite; 53 | animation: nprogress-spinner 400ms linear infinite; 54 | } 55 | 56 | .nprogress-custom-parent { 57 | overflow: hidden; 58 | position: relative; 59 | } 60 | 61 | .nprogress-custom-parent #nprogress .spinner, 62 | .nprogress-custom-parent #nprogress .bar { 63 | position: absolute; 64 | } 65 | 66 | @-webkit-keyframes nprogress-spinner { 67 | 0% { -webkit-transform: rotate(0deg); } 68 | 100% { -webkit-transform: rotate(360deg); } 69 | } 70 | @keyframes nprogress-spinner { 71 | 0% { transform: rotate(0deg); } 72 | 100% { transform: rotate(360deg); } 73 | } 74 | -------------------------------------------------------------------------------- /plugins/pages/layout-now/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@nut-plugins/pages-layout-now", 3 | "version": "1.0.0-alpha.5", 4 | "publishConfig": { 5 | "access": "public" 6 | }, 7 | "description": "pages-layout-now", 8 | "keywords": [ 9 | "nut", 10 | "pages", 11 | "plugin" 12 | ], 13 | "main": "lib/index.js", 14 | "files": [ 15 | "lib" 16 | ], 17 | "engines": { 18 | "node": ">=8.9.0" 19 | }, 20 | "repository": "https://github.com/nut-project/nut/tree/master/plugins/pages/layout-now", 21 | "homepage": "http://nut.js.org", 22 | "bugs": { 23 | "url": "https://github.com/nut-project/nut/issues/new/choose" 24 | }, 25 | "scripts": {}, 26 | "author": { 27 | "name": "fengzilong", 28 | "email": "fengzilong1992@gmail.com", 29 | "url": "https://github.com/fengzilong" 30 | }, 31 | "license": "MIT", 32 | "dependencies": { 33 | "chalk": "^2.4.2", 34 | "cosmiconfig": "^5.2.1", 35 | "globby": "^10.0.1", 36 | "gradient-string": "^1.2.0", 37 | "signale": "^1.4.0" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /plugins/pages/layout-saber/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. 5 | 6 | # [1.0.0-alpha.4](https://github.com/nut-project/nut/tree/master/plugins/pages/layout-saber/compare/@nut-plugins/pages-layout-saber@1.0.0-alpha.3...@nut-plugins/pages-layout-saber@1.0.0-alpha.4) (2020-02-29) 7 | 8 | **Note:** Version bump only for package @nut-plugins/pages-layout-saber 9 | 10 | 11 | 12 | 13 | 14 | # [1.0.0-alpha.3](https://github.com/nut-project/nut/tree/master/plugins/pages/layout-saber/compare/@nut-plugins/pages-layout-saber@1.0.0-alpha.2...@nut-plugins/pages-layout-saber@1.0.0-alpha.3) (2019-12-06) 15 | 16 | **Note:** Version bump only for package @nut-plugins/pages-layout-saber 17 | -------------------------------------------------------------------------------- /plugins/pages/layout-saber/lib/index.js: -------------------------------------------------------------------------------- 1 | const path = require( 'path' ) 2 | 3 | exports.name = 'layout-saber' 4 | exports.apply = api => { 5 | api.addRuntimeModule( { 6 | file: path.join( __dirname, './runtime.js' ), 7 | } ) 8 | } 9 | -------------------------------------------------------------------------------- /plugins/pages/layout-saber/lib/index.module.less: -------------------------------------------------------------------------------- 1 | .shell { 2 | display: flex; 3 | flex-direction: column; 4 | min-height: 100%; 5 | } 6 | 7 | .header { 8 | position: sticky; 9 | top: 0; 10 | left: 0; 11 | right: 0; 12 | width: 100%; 13 | height: 60px; 14 | background-color: var(--primary-color); 15 | color: #fff; 16 | line-height: 60px; 17 | padding: 0 20px; 18 | display: flex; 19 | justify-content: space-between; 20 | font-size: 16px; 21 | z-index: 1; 22 | 23 | &__name { 24 | font-size: 22px; 25 | font-weight: bold; 26 | cursor: pointer; 27 | } 28 | 29 | &__user { 30 | cursor: default; 31 | } 32 | } 33 | 34 | .navbar { 35 | height: 60px; 36 | line-height: 60px; 37 | padding: 0 20px; 38 | background-color: #fff; 39 | font-size: 16px; 40 | 41 | &__items { 42 | display: flex; 43 | list-style: none; 44 | margin: 0; 45 | padding: 0; 46 | } 47 | 48 | &__item { 49 | height: 60px; 50 | box-sizing: border-box; 51 | 52 | &.is_active { 53 | border-bottom: solid 2px var(--primary-color); 54 | background-color: #fdfdfd; 55 | } 56 | 57 | a { 58 | display: block; 59 | width: 100%; 60 | height: 100%; 61 | padding: 0 20px; 62 | text-decoration: none; 63 | color: var(--primary-color); 64 | } 65 | } 66 | } 67 | 68 | .content { 69 | width: 100%; 70 | background-color: #f7f7f7; 71 | flex: 1; 72 | } 73 | 74 | .markdown { 75 | background-color: #fff; 76 | margin-top: 15px; 77 | padding: 30px 40px; 78 | } 79 | 80 | .other { 81 | min-height: 100vh; 82 | padding: 20px; 83 | } 84 | -------------------------------------------------------------------------------- /plugins/pages/layout-saber/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@nut-plugins/pages-layout-saber", 3 | "version": "1.0.0-alpha.5", 4 | "publishConfig": { 5 | "access": "public" 6 | }, 7 | "description": "pages-layout-saber", 8 | "keywords": [ 9 | "nut", 10 | "pages", 11 | "plugin" 12 | ], 13 | "main": "lib/index.js", 14 | "files": [ 15 | "lib" 16 | ], 17 | "engines": { 18 | "node": ">=8.9.0" 19 | }, 20 | "repository": "https://github.com/nut-project/nut/tree/master/plugins/pages/layout-saber", 21 | "homepage": "http://nut.js.org", 22 | "bugs": { 23 | "url": "https://github.com/nut-project/nut/issues/new/choose" 24 | }, 25 | "scripts": {}, 26 | "author": { 27 | "name": "fengzilong", 28 | "email": "fengzilong1992@gmail.com", 29 | "url": "https://github.com/fengzilong" 30 | }, 31 | "license": "MIT", 32 | "dependencies": { 33 | "chalk": "^2.4.2", 34 | "cosmiconfig": "^5.2.1", 35 | "globby": "^10.0.1", 36 | "gradient-string": "^1.2.0", 37 | "signale": "^1.4.0" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /plugins/pages/layout-side/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. 5 | 6 | # [1.0.0-alpha.3](https://github.com/nut-project/nut/tree/master/plugins/pages/layout-side/compare/@nut-plugins/pages-layout-side@1.0.0-alpha.2...@nut-plugins/pages-layout-side@1.0.0-alpha.3) (2020-02-29) 7 | 8 | **Note:** Version bump only for package @nut-plugins/pages-layout-side 9 | -------------------------------------------------------------------------------- /plugins/pages/layout-side/lib/index.js: -------------------------------------------------------------------------------- 1 | const path = require( 'path' ) 2 | 3 | exports.name = 'layout-side' 4 | exports.apply = api => { 5 | api.addRuntimeModule( { 6 | file: path.join( __dirname, './runtime.js' ), 7 | } ) 8 | } 9 | -------------------------------------------------------------------------------- /plugins/pages/layout-side/lib/tippy.js: -------------------------------------------------------------------------------- 1 | import tippy from 'tippy.js' 2 | import 'tippy.js/index.css' 3 | 4 | export default function ( Component ) { 5 | Component.directive( 'r-tippy', { 6 | link( el, expr ) { 7 | this.$watch( expr, ( options = {} ) => { 8 | if ( el._tippy ) { 9 | el._tippy.destroy() 10 | } 11 | 12 | tippy( el, { 13 | content: el.title, 14 | arrow: true, 15 | animateFill: false, 16 | animation: 'perspective', 17 | ...options 18 | } ) 19 | } ) 20 | 21 | return () => { 22 | if ( el._tippy ) { 23 | el._tippy.destroy() 24 | } 25 | } 26 | } 27 | } ) 28 | } 29 | -------------------------------------------------------------------------------- /plugins/pages/layout-side/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@nut-plugins/pages-layout-side", 3 | "version": "1.0.0-alpha.4", 4 | "publishConfig": { 5 | "access": "public" 6 | }, 7 | "description": "pages-layout-side", 8 | "keywords": [ 9 | "nut", 10 | "pages", 11 | "plugin" 12 | ], 13 | "main": "lib/index.js", 14 | "files": [ 15 | "lib" 16 | ], 17 | "engines": { 18 | "node": ">=8.9.0" 19 | }, 20 | "repository": "https://github.com/nut-project/nut/tree/master/plugins/pages/layout-side", 21 | "homepage": "http://nut.js.org", 22 | "bugs": { 23 | "url": "https://github.com/nut-project/nut/issues/new/choose" 24 | }, 25 | "scripts": {}, 26 | "author": { 27 | "name": "fengzilong", 28 | "email": "fengzilong1992@gmail.com", 29 | "url": "https://github.com/fengzilong" 30 | }, 31 | "license": "MIT", 32 | "dependencies": { 33 | "chalk": "^2.4.2", 34 | "cosmiconfig": "^5.2.1", 35 | "globby": "^10.0.1", 36 | "gradient-string": "^1.2.0", 37 | "signale": "^1.4.0" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /plugins/pages/materials/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. 5 | 6 | # 1.0.0-alpha.4 (2019-12-06) 7 | 8 | 9 | ### Bug Fixes 10 | 11 | * only add runtime in development mode ([8cee15b](https://github.com/nut-project/nut/tree/master/plugins/pages/materials/commit/8cee15bdf04feae71b09f399b7eb927312175a35)) 12 | 13 | 14 | ### Features 15 | 16 | * add --analyze and --profile flags ([af79a4d](https://github.com/nut-project/nut/tree/master/plugins/pages/materials/commit/af79a4da34b0d748cfb7423d4b6684f812da75c9)) 17 | * add materials plugin ([ea14f1c](https://github.com/nut-project/nut/tree/master/plugins/pages/materials/commit/ea14f1cbcef1cf9df0b8537d480735eaf0912df5)) 18 | * support add block ([#65](https://github.com/nut-project/nut/tree/master/plugins/pages/materials/issues/65)) ([0d4073a](https://github.com/nut-project/nut/tree/master/plugins/pages/materials/commit/0d4073adf65ed39859c395e22e9d20133b0dad44)) 19 | -------------------------------------------------------------------------------- /plugins/pages/materials/lib/runtime/index.module.less: -------------------------------------------------------------------------------- 1 | @import './var.less'; 2 | 3 | .transition { 4 | transform: translate3d(0,0,0); 5 | transition: transform .3s ease; 6 | } 7 | 8 | .offset { 9 | transform: translate3d(-@panel-width,0,0); 10 | } 11 | -------------------------------------------------------------------------------- /plugins/pages/materials/lib/runtime/var.less: -------------------------------------------------------------------------------- 1 | @panel-width: 400px; 2 | -------------------------------------------------------------------------------- /plugins/pages/materials/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@nut-plugins/pages-materials", 3 | "version": "1.0.0-alpha.5", 4 | "publishConfig": { 5 | "access": "public" 6 | }, 7 | "description": "materials", 8 | "keywords": [ 9 | "nut", 10 | "pages", 11 | "plugin" 12 | ], 13 | "main": "lib/index.js", 14 | "files": [ 15 | "lib" 16 | ], 17 | "engines": { 18 | "node": ">=8.9.0" 19 | }, 20 | "repository": "https://github.com/nut-project/nut/tree/master/plugins/pages/materials", 21 | "homepage": "http://nut.js.org", 22 | "bugs": { 23 | "url": "https://github.com/nut-project/nut/issues/new/choose" 24 | }, 25 | "scripts": {}, 26 | "author": { 27 | "name": "fengzilong", 28 | "email": "fengzilong1992@gmail.com", 29 | "url": "https://github.com/fengzilong" 30 | }, 31 | "license": "MIT", 32 | "dependencies": { 33 | "@zeit-ui/themes": "^0.1.0", 34 | "@zeit-ui/vue": "^2.0.0-alpha.0", 35 | "axios": "^0.19.0", 36 | "fs-extra": "^8.1.0", 37 | "gunzip-maybe": "^1.4.1", 38 | "jscodeshift": "^0.6.4", 39 | "pascalcase": "^1.0.0", 40 | "tar-stream": "^2.1.0", 41 | "vue-template-compiler": "^2.6.10" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /plugins/pages/microfrontends/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. 5 | 6 | # [1.0.0-alpha.5](https://github.com/nut-project/nut/tree/master/plugins/pages/microfrontends/compare/@nut-plugins/pages-microfrontends@1.0.0-alpha.4...@nut-plugins/pages-microfrontends@1.0.0-alpha.5) (2019-12-19) 7 | 8 | 9 | ### Bug Fixes 10 | 11 | * traverse sidebar to get first route ([075b04f](https://github.com/nut-project/nut/tree/master/plugins/pages/microfrontends/commit/075b04f1032e66a9d01f1f2c29ae2ec23f25590c)) 12 | 13 | 14 | 15 | 16 | 17 | # [1.0.0-alpha.4](https://github.com/nut-project/nut/tree/master/plugins/pages/microfrontends/compare/@nut-plugins/pages-microfrontends@1.0.0-alpha.3...@nut-plugins/pages-microfrontends@1.0.0-alpha.4) (2019-12-06) 18 | 19 | 20 | ### Features 21 | 22 | * add --analyze and --profile flags ([af79a4d](https://github.com/nut-project/nut/tree/master/plugins/pages/microfrontends/commit/af79a4da34b0d748cfb7423d4b6684f812da75c9)) 23 | * add materials plugin ([ea14f1c](https://github.com/nut-project/nut/tree/master/plugins/pages/microfrontends/commit/ea14f1cbcef1cf9df0b8537d480735eaf0912df5)) 24 | * support add block ([#65](https://github.com/nut-project/nut/tree/master/plugins/pages/microfrontends/issues/65)) ([0d4073a](https://github.com/nut-project/nut/tree/master/plugins/pages/microfrontends/commit/0d4073adf65ed39859c395e22e9d20133b0dad44)) 25 | * use applescript to open chrome ([4a348de](https://github.com/nut-project/nut/tree/master/plugins/pages/microfrontends/commit/4a348defb8accec833312de6571c70b664522665)) 26 | -------------------------------------------------------------------------------- /plugins/pages/microfrontends/files/core/homepage.js: -------------------------------------------------------------------------------- 1 | export default { 2 | _value: null, 3 | 4 | set( page ) { 5 | this._value = page 6 | }, 7 | 8 | get() { 9 | return this._value 10 | }, 11 | } 12 | -------------------------------------------------------------------------------- /plugins/pages/microfrontends/files/core/page.js: -------------------------------------------------------------------------------- 1 | const accessors = {} 2 | 3 | export default function ( page ) { 4 | if ( accessors[ page ] ) { 5 | return accessors[ page ] 6 | } 7 | 8 | accessors[ page ] = { 9 | page, 10 | attributes: {}, 11 | get( k ) { 12 | return this.attributes[ k ] 13 | }, 14 | set( k, v ) { 15 | this.attributes[ k ] = v 16 | } 17 | } 18 | 19 | return accessors[ page ] 20 | } 21 | -------------------------------------------------------------------------------- /plugins/pages/microfrontends/files/core/quicklink.js: -------------------------------------------------------------------------------- 1 | import quicklink from 'quicklink' 2 | 3 | // globals, pages 4 | export default function ( context ) { 5 | return { 6 | prefetch( toPrefetchPages = [], options = {} ) { 7 | const chunks = context.globals.STATS_ASSETS_BY_CHUNKNAME || {} 8 | const publicPath = context.globals.PUBLIC_PATH || '/' 9 | const pages = context.pages || [] 10 | 11 | const names = toPrefetchPages 12 | .map( page => { 13 | return pages.find( p => p.page === page ) 14 | } ) 15 | .filter( Boolean ) 16 | .map( p => p.name ) 17 | 18 | let urls = names.reduce( ( total, name ) => { 19 | const urls = ensureArray( chunks[ name ] || [] ) 20 | .map( url => publicPath + url ) 21 | 22 | total.push( ...urls ) 23 | 24 | return total 25 | }, [] ) 26 | 27 | const sourceMapReg = /\.map$/ 28 | 29 | urls = urls.filter( url => !sourceMapReg.test( url ) ) 30 | 31 | quicklink( { 32 | ...options, 33 | urls 34 | } ) 35 | }, 36 | 37 | prefetchUrls( urls = [], options = {} ) { 38 | quicklink( { 39 | ...options, 40 | urls 41 | } ) 42 | }, 43 | } 44 | } 45 | 46 | function isArray( obj ) { 47 | return toString.call( obj ) === '[object Array]' 48 | } 49 | 50 | function ensureArray( value ) { 51 | if ( !isArray( value ) ) { 52 | return [ value ] 53 | } 54 | 55 | return value 56 | } 57 | -------------------------------------------------------------------------------- /plugins/pages/microfrontends/files/css/override.less: -------------------------------------------------------------------------------- 1 | .nut-language-highlight { 2 | position: relative; 3 | } 4 | 5 | pre[class*="language-"], pre[data-lang] { 6 | font-size: 14px; 7 | position: static; 8 | } 9 | 10 | code[class*="language-"], pre[class*="language-"], code { 11 | font-family: 'Source Code Pro', monospace; 12 | } 13 | 14 | pre[data-lang]::before { 15 | position: absolute; 16 | top: 0px; 17 | right: 20px; 18 | font-size: 12px; 19 | padding: 1px 10px; 20 | text-align: right; 21 | color: #444; 22 | font-weight: 700; 23 | letter-spacing: .8px; 24 | text-transform: uppercase; 25 | border-radius: 0 0 5px 5px; 26 | background: #ddd; 27 | content: attr(data-lang); 28 | } 29 | 30 | pre[class='language-javascript']::before { 31 | background: #f7df1e; 32 | } 33 | 34 | pre[class='language-js']::before { 35 | background: #f7df1e; 36 | } 37 | 38 | pre[class='language-jsx']::before { 39 | background: #61dafb; 40 | } 41 | 42 | pre[class='language-graphql']::before { 43 | background: #E10098; 44 | color: #fff; 45 | font-weight: 400; 46 | } 47 | 48 | pre[class='language-html']::before { 49 | background: #3192d9; 50 | color: #fff; 51 | font-weight: 400; 52 | } 53 | 54 | pre[class='language-css']::before { 55 | background: #eeb72d; 56 | color: #fff; 57 | font-weight: 400; 58 | } 59 | 60 | pre[class='language-shell']::before { 61 | } 62 | 63 | pre[class='language-sh']::before { 64 | } 65 | 66 | pre[class='language-bash']::before { 67 | } 68 | 69 | pre[class='language-yaml']::before { 70 | background: #ffa8df; 71 | } 72 | 73 | pre[class='language-markdown']::before { 74 | } 75 | 76 | pre[class='language-json']::before, pre[class='language-json5']::before { 77 | background: linen; 78 | } 79 | 80 | pre[class='language-diff']::before { 81 | background: #e6ffed; 82 | } 83 | 84 | pre[class='language-text']::before { 85 | background: #fff; 86 | } 87 | 88 | pre[class='language-flow']::before { 89 | background: #E8BD36; 90 | } 91 | -------------------------------------------------------------------------------- /plugins/pages/microfrontends/files/css/reset.less: -------------------------------------------------------------------------------- 1 | html, body { 2 | font-family: 'Nunito', sans-serif; 3 | margin: 0; 4 | padding: 0; 5 | box-sizing: border-box; 6 | } 7 | 8 | html * { 9 | box-sizing: inherit; 10 | } 11 | -------------------------------------------------------------------------------- /plugins/pages/microfrontends/files/entries/child.js: -------------------------------------------------------------------------------- 1 | /* global window, document */ 2 | 3 | import context from '#context' 4 | 5 | if ( window.nutJsonp ) { 6 | const { pages, app: config, routes } = context 7 | const currentScript = document.currentScript 8 | const dataset = currentScript ? currentScript.dataset : {} 9 | 10 | window.nutJsonp( { 11 | pages, 12 | config, 13 | routes, 14 | }, dataset ) 15 | } 16 | -------------------------------------------------------------------------------- /plugins/pages/microfrontends/files/fonts/iconfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nut-project/nut/672e123a975dc02ffc12a5bbad31a2c5a49fc776/plugins/pages/microfrontends/files/fonts/iconfont.eot -------------------------------------------------------------------------------- /plugins/pages/microfrontends/files/fonts/iconfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nut-project/nut/672e123a975dc02ffc12a5bbad31a2c5a49fc776/plugins/pages/microfrontends/files/fonts/iconfont.ttf -------------------------------------------------------------------------------- /plugins/pages/microfrontends/files/fonts/iconfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nut-project/nut/672e123a975dc02ffc12a5bbad31a2c5a49fc776/plugins/pages/microfrontends/files/fonts/iconfont.woff -------------------------------------------------------------------------------- /plugins/pages/microfrontends/files/fonts/iconfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nut-project/nut/672e123a975dc02ffc12a5bbad31a2c5a49fc776/plugins/pages/microfrontends/files/fonts/iconfont.woff2 -------------------------------------------------------------------------------- /plugins/pages/microfrontends/files/modules/layout-none.js: -------------------------------------------------------------------------------- 1 | /* global document */ 2 | 3 | export default async ctx => { 4 | let container 5 | let mountNode 6 | 7 | await ctx.api.layout.register( { 8 | name: 'none', 9 | 10 | mount( node ) { 11 | container = document.createElement( 'div' ) 12 | mountNode = document.createElement( 'div' ) 13 | container.appendChild( mountNode ) 14 | 15 | node.appendChild( container ) 16 | }, 17 | 18 | unmount( node ) { 19 | if ( node && container && ( container.parentNode === node ) ) { 20 | node.removeChild( container ) 21 | } 22 | }, 23 | 24 | getMountNode() { 25 | return mountNode 26 | }, 27 | } ) 28 | } 29 | -------------------------------------------------------------------------------- /plugins/pages/microfrontends/files/steps/setup-nico.js: -------------------------------------------------------------------------------- 1 | import createNico from '../core/nico' 2 | 3 | export default function ( ctx, routes, root, router, pluginOptions ) { 4 | const nico = createNico( ctx, root, router, pluginOptions ) 5 | 6 | nico.define( routes ) 7 | 8 | return nico 9 | } 10 | -------------------------------------------------------------------------------- /plugins/pages/microfrontends/files/utils/add-require-ensure.js: -------------------------------------------------------------------------------- 1 | export default () => { 2 | return import( './dynamic-import-fixture' ) 3 | } 4 | -------------------------------------------------------------------------------- /plugins/pages/microfrontends/files/utils/dynamic-import-fixture.js: -------------------------------------------------------------------------------- 1 | export default () => {} 2 | -------------------------------------------------------------------------------- /plugins/pages/microfrontends/files/utils/get-first-route.js: -------------------------------------------------------------------------------- 1 | export default function getFirstRoute( context ) { 2 | let found 3 | 4 | const sidebar = context.api.sidebar.get() 5 | 6 | walkChildren( sidebar, null, child => { 7 | if ( child.page && !found ) { 8 | found = child 9 | } 10 | } ) 11 | 12 | if ( !found || !found.page ) { 13 | return 14 | } 15 | 16 | return found.page.route 17 | } 18 | 19 | function walkChildren( children, parent, callback ) { 20 | if ( !children ) { 21 | return 22 | } 23 | 24 | if ( Array.isArray( children ) ) { 25 | children.forEach( ( v, i ) => { 26 | callback( v, i, parent ) 27 | 28 | if ( Array.isArray( v.children ) ) { 29 | walkChildren( v.children, v, callback ) 30 | } 31 | } ) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /plugins/pages/microfrontends/files/utils/logger.js: -------------------------------------------------------------------------------- 1 | export default { 2 | success( scope, message ) { 3 | console.log( 4 | '\n%c' + scope + '%c' + message + '%c\n', 5 | 'background-color: #0089ff;color: #fff;padding: 2px 6px;', 6 | 'background-color: #3c3e6f;color: #fff;padding: 2px 6px;', 7 | '' 8 | ) 9 | }, 10 | 11 | error( scope, message ) { 12 | console.log( 13 | '\n%c' + scope + '%c' + message + '%c\n', 14 | 'background-color: #ff8787;color: #fff;padding: 2px 6px;', 15 | 'background-color: #e74d54;color: #fff;padding: 2px 6px;', 16 | '' 17 | ) 18 | }, 19 | 20 | warning( scope, message ) { 21 | console.log( 22 | '\n%c' + scope + '%c' + message + '%c\n', 23 | 'background-color: #eccd70;color: #fff;padding: 2px 6px;', 24 | 'background-color: #e6ba50;color: #fff;padding: 2px 6px;', 25 | '' 26 | ) 27 | }, 28 | 29 | info( scope, message ) { 30 | console.log( 31 | '\n%c' + scope + '%c' + message + '%c\n', 32 | 'background-color: #0089ff;color: #fff;padding: 2px 6px;', 33 | 'background-color: #3c3e6f;color: #fff;padding: 2px 6px;', 34 | '' 35 | ) 36 | }, 37 | } 38 | -------------------------------------------------------------------------------- /plugins/pages/microfrontends/files/utils/normalize-route.js: -------------------------------------------------------------------------------- 1 | export default function normalizeRoute( str ) { 2 | str = str.replace( /^\/+/, '/' ) 3 | str = str.replace( /\/+$/, '' ) 4 | 5 | if ( str.charAt( 0 ) !== '/' ) { 6 | return '/' + str 7 | } 8 | 9 | return str 10 | } 11 | -------------------------------------------------------------------------------- /plugins/pages/microfrontends/files/utils/switch-theme.js: -------------------------------------------------------------------------------- 1 | /* global document */ 2 | 3 | export default function switchTheme( theme ) { 4 | switch ( theme ) { 5 | case 'ocean': 6 | document.documentElement.style.setProperty( '--primary-color', '#79bef6' ) 7 | document.documentElement.style.setProperty( '--primary-color-dark', '#568ffd' ) 8 | break 9 | case 'sakura': 10 | document.documentElement.style.setProperty( '--primary-color', '#f67995' ) 11 | document.documentElement.style.setProperty( '--primary-color-dark', '#ff6a8b' ) 12 | break 13 | default: 14 | break 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /plugins/pages/microfrontends/lib/loader/mdx-arrtibutes.js: -------------------------------------------------------------------------------- 1 | const fm = require( 'front-matter' ) 2 | 3 | module.exports = function ( source ) { 4 | const result = fm( source ) 5 | const content = result.body || '' 6 | const attributes = result.attributes || {} 7 | 8 | return ` 9 | ${ content } 10 | export const attributes = ${ JSON.stringify( attributes ) } 11 | ` 12 | } 13 | -------------------------------------------------------------------------------- /plugins/pages/microfrontends/lib/loader/mount-markdown.js: -------------------------------------------------------------------------------- 1 | const fm = require( 'front-matter' ) 2 | const pathUtils = require( '../utils/path-utils' ) 3 | const marked = require( '../utils/marked' ) 4 | 5 | module.exports = function ( source ) { 6 | const nutifyPath = pathUtils.toRelative( require.resolve( './nutify/markdown' ) ) 7 | 8 | const result = fm( source ) 9 | 10 | const html = marked( result.body ) 11 | 12 | return ` 13 | import nutify from '${ nutifyPath }' 14 | export default nutify( { 15 | default: ${ JSON.stringify( html ) }, 16 | attributes: ${ JSON.stringify( result.attributes || {} ) }, 17 | } ) 18 | ` 19 | } 20 | -------------------------------------------------------------------------------- /plugins/pages/microfrontends/lib/loader/mount-react.js: -------------------------------------------------------------------------------- 1 | const qs = require( 'querystring' ) 2 | const pathUtils = require( '../utils/path-utils' ) 3 | 4 | module.exports = source => source 5 | 6 | module.exports.pitch = function ( remainingRequest ) { 7 | const query = qs.parse( this.resourceQuery.slice( 1 ) ) 8 | 9 | const nutifyPath = pathUtils.toRelative( require.resolve( './nutify/react.js' ) ) 10 | 11 | // only pitch for first time 12 | if ( typeof query.vue === 'undefined' ) { 13 | return ` 14 | import * as all from ${ JSON.stringify( '-!' + remainingRequest ) }; 15 | import nutify from '${ nutifyPath }' 16 | 17 | // all: default + attributes 18 | export default nutify( all ) 19 | ` 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /plugins/pages/microfrontends/lib/loader/mount-vue.js: -------------------------------------------------------------------------------- 1 | const qs = require( 'querystring' ) 2 | const pathUtils = require( '../utils/path-utils' ) 3 | 4 | module.exports = source => source 5 | 6 | module.exports.pitch = function ( remainingRequest ) { 7 | const query = qs.parse( this.resourceQuery.slice( 1 ) ) 8 | 9 | const nutifyPath = pathUtils.toRelative( require.resolve( './nutify/vue' ) ) 10 | 11 | // only pitch for first time 12 | if ( typeof query.vue === 'undefined' ) { 13 | return ` 14 | import * as all from ${ JSON.stringify( '-!' + remainingRequest ) }; 15 | import nutify from '${ nutifyPath }' 16 | 17 | // all: default + attributes 18 | export default nutify( all ) 19 | ` 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /plugins/pages/microfrontends/lib/loader/nutify/markdown.js: -------------------------------------------------------------------------------- 1 | export default function ( all = {} ) { 2 | const source = all.default || '' 3 | const attributes = all.attributes || {} 4 | 5 | return { 6 | $$nut() { 7 | return { 8 | attributes, 9 | 10 | mount( node ) { 11 | node.innerHTML = source 12 | }, 13 | 14 | unmount( node ) { 15 | node.innerHTML = '' 16 | }, 17 | } 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /plugins/pages/microfrontends/lib/modules/command-palette/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nut-project/nut/672e123a975dc02ffc12a5bbad31a2c5a49fc776/plugins/pages/microfrontends/lib/modules/command-palette/logo.png -------------------------------------------------------------------------------- /plugins/pages/microfrontends/lib/utils.js: -------------------------------------------------------------------------------- 1 | const path = require( 'path' ) 2 | const hashsum = require( 'hash-sum' ) 3 | 4 | exports.getUniqueApplicationId = function getUniqueApplicationId( config ) { 5 | let pkg = {} 6 | try { 7 | pkg = require( process.cwd() + '/package.json' ) 8 | } catch ( e ) {} 9 | 10 | return hashsum( { 11 | pkg, 12 | config, 13 | } ) 14 | } 15 | 16 | function normalize( filepath ) { 17 | return filepath.replace( /\\/g, '/' ) 18 | } 19 | 20 | const projectRoot = path.join( process.cwd(), 'src' ) 21 | 22 | function toRelativePath( filepath ) { 23 | return '@/' + normalize( path.relative( projectRoot, filepath ) ) 24 | } 25 | 26 | exports.toRelativePath = toRelativePath 27 | -------------------------------------------------------------------------------- /plugins/pages/microfrontends/lib/utils/dirs.js: -------------------------------------------------------------------------------- 1 | const path = require( 'path' ) 2 | 3 | module.exports = { 4 | root: path.join( __dirname, '../../' ), 5 | project: process.cwd(), 6 | } 7 | -------------------------------------------------------------------------------- /plugins/pages/microfrontends/lib/utils/path-utils.js: -------------------------------------------------------------------------------- 1 | const path = require( 'path' ) 2 | 3 | function normalize( filepath ) { 4 | return filepath.replace( /\\/g, '/' ) 5 | } 6 | 7 | const projectRoot = path.join( process.cwd(), 'src' ) 8 | 9 | function toRelative( filepath ) { 10 | return '@/' + normalize( path.relative( projectRoot, filepath ) ) 11 | } 12 | 13 | module.exports = { 14 | normalize, 15 | toRelative, 16 | } 17 | -------------------------------------------------------------------------------- /plugins/pages/microfrontends/lib/webpack/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nut-project/nut/672e123a975dc02ffc12a5bbad31a2c5a49fc776/plugins/pages/microfrontends/lib/webpack/favicon.ico -------------------------------------------------------------------------------- /plugins/pages/microfrontends/lib/webpack/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nut-project/nut/672e123a975dc02ffc12a5bbad31a2c5a49fc776/plugins/pages/microfrontends/lib/webpack/favicon.png -------------------------------------------------------------------------------- /plugins/pages/microfrontends/lib/webpack/get-babel-options.js: -------------------------------------------------------------------------------- 1 | module.exports = ( { browserslist } = {} ) => { 2 | return { 3 | presets: [ 4 | [ 5 | require.resolve( '@babel/preset-env' ), 6 | { 7 | targets: { 8 | browsers: browserslist 9 | } 10 | } 11 | ] 12 | ], 13 | plugins: [ 14 | require.resolve( '@babel/plugin-transform-runtime' ), 15 | require.resolve( '@babel/plugin-syntax-dynamic-import' ), 16 | ], 17 | sourceType: 'unambiguous', 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /plugins/pages/microfrontends/lib/webpack/mdx/provider.js: -------------------------------------------------------------------------------- 1 | // not used currently 2 | 3 | export default { 4 | props: { 5 | components: Object, 6 | required: true 7 | }, 8 | provide() { 9 | return { 10 | contextComponents: this.components 11 | } 12 | }, 13 | render( h ) { 14 | return h( 'div', {}, [ 15 | this.$slots.default 16 | ] ) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /plugins/pages/microfrontends/lib/webpack/mdx/tag.js: -------------------------------------------------------------------------------- 1 | const defaults = { 2 | inlineCode: 'code', 3 | wrapper: 'div' 4 | } 5 | 6 | export default { 7 | props: { 8 | name: String, 9 | components: { 10 | type: Object, 11 | default: () => ( {} ) 12 | }, 13 | cprops: { 14 | type: Object, 15 | default: () => ( {} ) 16 | }, 17 | Layout: Object, 18 | layoutProps: { 19 | type: Object, 20 | default: () => ( {} ) 21 | }, 22 | }, 23 | inject: { 24 | contextComponents: { 25 | default: {} 26 | } 27 | }, 28 | render( h ) { 29 | if ( this.Layout ) { 30 | return h( this.Layout, { 31 | props: { 32 | attrs: this.layoutProps 33 | } 34 | }, [ this.$slots.default ] ) 35 | } 36 | 37 | // eslint-disable-next-line 38 | const Component = 39 | this.components[ this.name ] || 40 | // this.contextComponents[ this.name ] || 41 | defaults[ this.name ] || 42 | this.name 43 | const childProps = { ...this.cprops } 44 | 45 | const options = { 46 | attrs: childProps, 47 | props: childProps, 48 | } 49 | 50 | if ( childProps.class ) { 51 | options.class = childProps.class.split( /\s+/ ) 52 | } 53 | 54 | return h( Component, options, [ this.$slots.default ] ) 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /plugins/pages/microfrontends/lib/webpack/mdx/vue-loader.js: -------------------------------------------------------------------------------- 1 | const { getOptions } = require( 'loader-utils' ) 2 | const mdx = require( '@mdx-js/mdx' ) 3 | const path = require( 'path' ) 4 | 5 | module.exports = async function ( content ) { 6 | const callback = this.async() 7 | const options = Object.assign( {}, getOptions( this ), { 8 | filepath: this.resourcePath 9 | } ) 10 | let result 11 | 12 | try { 13 | result = await mdx( content, { ...options, skipExport: true } ) 14 | } catch ( err ) { 15 | return callback( err ) 16 | } 17 | 18 | const code = `// vue babel plugin doesn't support the pragma replacement 19 | import { mdx } from '@mdx-js/vue' 20 | import MDXTag from ${ JSON.stringify( path.join( __dirname, './tag.js' ) ) } 21 | 22 | let h; 23 | ${ result } 24 | 25 | export default { 26 | name: 'Mdx', 27 | render(vueCreateElement) { 28 | h = mdx.bind({vueCreateElement}) 29 | // maybe refers to this in vue.md 30 | return MDXContent.call(this, {}) 31 | } 32 | } 33 | ` 34 | 35 | return callback( null, code ) 36 | } 37 | -------------------------------------------------------------------------------- /plugins/pages/microfrontends/lib/webpack/template.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | <%= htmlWebpackPlugin.options.title %> 8 | 9 | 10 | 13 | 19 |
20 | 21 | 22 | -------------------------------------------------------------------------------- /plugins/pages/microfrontends/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@nut-plugins/pages-microfrontends", 3 | "version": "1.0.0-alpha.6", 4 | "publishConfig": { 5 | "access": "public" 6 | }, 7 | "description": "microfrontends", 8 | "keywords": [ 9 | "nut", 10 | "pages", 11 | "plugin" 12 | ], 13 | "main": "lib/index.js", 14 | "files": [ 15 | "lib", 16 | "files" 17 | ], 18 | "engines": { 19 | "node": ">=8.9.0" 20 | }, 21 | "repository": "https://github.com/nut-project/nut/tree/master/plugins/pages/microfrontends", 22 | "homepage": "http://nut.js.org", 23 | "bugs": { 24 | "url": "https://github.com/nut-project/nut/issues/new/choose" 25 | }, 26 | "scripts": {}, 27 | "author": { 28 | "name": "fengzilong", 29 | "email": "fengzilong1992@gmail.com", 30 | "url": "https://github.com/fengzilong" 31 | }, 32 | "license": "MIT", 33 | "dependencies": { 34 | "@mapbox/rehype-prism": "^0.3.1", 35 | "@mdx-js/mdx": "^1.0.21", 36 | "@mdx-js/vue": "1.0.20", 37 | "@nut-project/dev-utils": "^1.0.0-alpha.4", 38 | "@sindresorhus/slugify": "^0.9.1", 39 | "address": "^1.1.2", 40 | "axios": "^0.19.0", 41 | "boxen": "^4.1.0", 42 | "deepmerge": "^4.0.0", 43 | "docsearch.js": "^2.6.3", 44 | "front-matter": "^3.0.1", 45 | "fs-extra": "^8.1.0", 46 | "hash-sum": "^2.0.0", 47 | "headroom.js": "^0.9.4", 48 | "marked": "^0.6.1", 49 | "mdast-util-toc": "^4.2.0", 50 | "nprogress": "^0.2.0", 51 | "popper.js": "^1.15.0", 52 | "pretty-bytes": "^5.2.0", 53 | "prism-themes": "^1.1.0", 54 | "prismjs": "^1.16.0", 55 | "query-string": "5", 56 | "quicklink": "^1.0.0", 57 | "react": "^16.8.6", 58 | "react-dom": "^16.8.6", 59 | "regularjs": "^0.6.2", 60 | "rehype-slug": "^2.0.3", 61 | "resolve-from": "^5.0.0", 62 | "string-width": "^4.1.0", 63 | "text-table": "^0.2.0", 64 | "tippy.js": "^4.2.1", 65 | "unfancy-router": "0.1.10", 66 | "unist-util-visit": "^1.4.1", 67 | "webpack-stats-plugin": "^0.3.0", 68 | "ws": "^7.1.2" 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /plugins/pages/runtime-vue/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. 5 | 6 | # 1.0.0-alpha.4 (2019-12-06) 7 | 8 | **Note:** Version bump only for package @nut-plugins/pages-runtime-vue 9 | -------------------------------------------------------------------------------- /plugins/pages/runtime-vue/files/App.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | -------------------------------------------------------------------------------- /plugins/pages/runtime-vue/files/app.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import createRouter from './router' 3 | import App from './App.vue' 4 | import context from '#context' 5 | 6 | const mode = ( context.app.router && context.app.router.mode ) || 'history' 7 | const routes = [ 8 | { path: '/', component: () => import( /* webpackChunkName: "home" */ '@/pages/home.vue' ) }, 9 | { path: '/hello', component: () => import( /* webpackChunkName: "hello" */ '@/pages/hello.vue' ) }, 10 | ] 11 | 12 | export default () => { 13 | const router = createRouter( { 14 | mode, 15 | routes, 16 | } ) 17 | 18 | const app = new Vue( { 19 | router, 20 | render: h => h( App ) 21 | } ) 22 | 23 | return { 24 | app, 25 | router, 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /plugins/pages/runtime-vue/files/entry-client.js: -------------------------------------------------------------------------------- 1 | import createApp from './app' 2 | 3 | export default () => { 4 | const { app, router } = createApp() 5 | 6 | router.onReady( () => { 7 | app.$mount( '#app' ) 8 | } ) 9 | } 10 | -------------------------------------------------------------------------------- /plugins/pages/runtime-vue/files/entry-server.js: -------------------------------------------------------------------------------- 1 | import createApp from './app' 2 | 3 | export default context => { 4 | return new Promise( ( resolve, reject ) => { 5 | const { app, router } = createApp() 6 | 7 | router.push( context.url ) 8 | 9 | router.onReady( () => { 10 | const matchedComponents = router.getMatchedComponents() 11 | if ( !matchedComponents.length ) { 12 | return reject( { code: 404 } ) 13 | } 14 | 15 | resolve( app ) 16 | }, reject ) 17 | } ) 18 | } 19 | -------------------------------------------------------------------------------- /plugins/pages/runtime-vue/files/router.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Router from 'vue-router' 3 | 4 | Vue.use( Router ) 5 | 6 | export function createRouter( { mode, routes } = {} ) { 7 | return new Router( { 8 | mode, 9 | routes, 10 | } ) 11 | } 12 | -------------------------------------------------------------------------------- /plugins/pages/runtime-vue/lib/index.js: -------------------------------------------------------------------------------- 1 | const path = require( 'path' ) 2 | 3 | const ID = 'runtime-vue' 4 | 5 | module.exports = { 6 | name: ID, 7 | 8 | core: true, 9 | 10 | async apply( api ) { 11 | api.hooks.chainWebpack.tapPromise( ID, async config => { 12 | config 13 | .resolve 14 | .alias 15 | .set( '@', path.join( process.cwd(), 'src' ) ) 16 | } ) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /plugins/pages/runtime-vue/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@nut-plugins/pages-runtime-vue", 3 | "version": "1.0.0-alpha.5", 4 | "publishConfig": { 5 | "access": "public" 6 | }, 7 | "description": "runtime-vue", 8 | "keywords": [ 9 | "nut", 10 | "pages", 11 | "plugin" 12 | ], 13 | "main": "lib/index.js", 14 | "files": [ 15 | "lib", 16 | "files" 17 | ], 18 | "engines": { 19 | "node": ">=8.9.0" 20 | }, 21 | "repository": "https://github.com/nut-project/nut/tree/master/plugins/pages/runtime-vue", 22 | "homepage": "http://nut.js.org", 23 | "bugs": { 24 | "url": "https://github.com/nut-project/nut/issues/new/choose" 25 | }, 26 | "scripts": {}, 27 | "author": { 28 | "name": "fengzilong", 29 | "email": "fengzilong1992@gmail.com", 30 | "url": "https://github.com/fengzilong" 31 | }, 32 | "license": "MIT" 33 | } 34 | -------------------------------------------------------------------------------- /plugins/vue-ssr/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. 5 | 6 | # [1.0.0-alpha.8](https://github.com/nut-project/nut/tree/master/plugins/vue-ssr/compare/@nut-plugins/vue-ssr@1.0.0-alpha.7...@nut-plugins/vue-ssr@1.0.0-alpha.8) (2019-12-16) 7 | 8 | 9 | ### Features 10 | 11 | * expose output.html.template ([d0f2ed9](https://github.com/nut-project/nut/tree/master/plugins/vue-ssr/commit/d0f2ed98c6287319b70e73d8bcf2559218971027)) 12 | 13 | 14 | 15 | 16 | 17 | # [1.0.0-alpha.7](https://github.com/nut-project/nut/tree/master/plugins/vue-ssr/compare/@nut-plugins/vue-ssr@1.0.0-alpha.6...@nut-plugins/vue-ssr@1.0.0-alpha.7) (2019-12-13) 18 | 19 | 20 | ### Features 21 | 22 | * add css.extract option ([30f4ef1](https://github.com/nut-project/nut/tree/master/plugins/vue-ssr/commit/30f4ef153bd16c300a48ec0b78f67e1073aedaba)) 23 | 24 | 25 | 26 | 27 | 28 | # [1.0.0-alpha.6](https://github.com/nut-project/nut/tree/master/plugins/vue-ssr/compare/@nut-plugins/vue-ssr@1.0.0-alpha.5...@nut-plugins/vue-ssr@1.0.0-alpha.6) (2019-12-13) 29 | 30 | 31 | ### Bug Fixes 32 | 33 | * use vue-server-renderer in user project ([aa86bdd](https://github.com/nut-project/nut/tree/master/plugins/vue-ssr/commit/aa86bdd0694478949bdfeada0dc63229de534ecc)) 34 | 35 | 36 | 37 | 38 | 39 | # 1.0.0-alpha.5 (2019-12-13) 40 | 41 | 42 | ### Features 43 | 44 | * add vue ssr ([3b3c3ed](https://github.com/nut-project/nut/tree/master/plugins/vue-ssr/commit/3b3c3ed9954d26ac5e06a7b6ef6aeccb702a6c57)) 45 | -------------------------------------------------------------------------------- /plugins/vue-ssr/lib/remove-magic-html.js: -------------------------------------------------------------------------------- 1 | module.exports = function ( serverOptions ) { 2 | const features = [] 3 | 4 | if ( serverOptions.compress ) { 5 | features.push( 'compress' ) 6 | } 7 | 8 | features.push( 'setup', 'before', 'headers', 'middleware' ) 9 | 10 | if ( serverOptions.proxy ) { 11 | features.push( 'proxy', 'middleware' ) 12 | } 13 | 14 | if ( serverOptions.contentBase !== false ) { 15 | features.push( 'contentBaseFiles' ) 16 | } 17 | 18 | if ( serverOptions.historyApiFallback ) { 19 | features.push( 'historyApiFallback', 'middleware' ) 20 | 21 | if ( serverOptions.contentBase !== false ) { 22 | features.push( 'contentBaseFiles' ) 23 | } 24 | } 25 | 26 | // features.push( 'contentBaseIndex' ) 27 | 28 | if ( serverOptions.watchContentBase ) { 29 | features.push( 'watchContentBase' ) 30 | } 31 | 32 | if ( serverOptions.after ) { 33 | features.push( 'after' ) 34 | } 35 | 36 | serverOptions.features = features 37 | } 38 | -------------------------------------------------------------------------------- /plugins/vue-ssr/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@nut-plugins/vue-ssr", 3 | "version": "1.0.0-alpha.9", 4 | "publishConfig": { 5 | "access": "public" 6 | }, 7 | "description": "vue ssr", 8 | "keywords": [ 9 | "nut", 10 | "vue", 11 | "ssr", 12 | "plugin" 13 | ], 14 | "main": "lib/index.js", 15 | "files": [ 16 | "lib", 17 | "files" 18 | ], 19 | "engines": { 20 | "node": ">=8.9.0" 21 | }, 22 | "repository": "https://github.com/nut-project/nut/tree/master/plugins/vue-ssr", 23 | "homepage": "http://nut.js.org", 24 | "bugs": { 25 | "url": "https://github.com/nut-project/nut/issues/new/choose" 26 | }, 27 | "scripts": {}, 28 | "author": { 29 | "name": "fengzilong", 30 | "email": "fengzilong1992@gmail.com", 31 | "url": "https://github.com/fengzilong" 32 | }, 33 | "license": "MIT", 34 | "dependencies": { 35 | "null-loader": "^3.0.0", 36 | "webpack-node-externals": "^1.7.2" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "config:base" 4 | ], 5 | "schedule": [ "every weekend" ] 6 | } 7 | -------------------------------------------------------------------------------- /scripts/dependency-check.js: -------------------------------------------------------------------------------- 1 | const check = require( 'dependency-check' ) 2 | const globby = require( 'globby' ) 3 | const path = require( 'path' ) 4 | const chalk = require( 'chalk' ) 5 | 6 | process 7 | .on( 'unhandledRejection', ( reason, p ) => { 8 | console.error( reason, 'Unhandled Rejection at Promise', p ) 9 | } ) 10 | 11 | ;( async () => { 12 | const files = await globby( [ 13 | 'packages/**/package.json', 14 | 'plugins/pages/**/package.json', 15 | '!packages/**/node_modules/**/package.json', 16 | '!plugins/**/node_modules/**/package.json', 17 | '!plugins/pages/microfrontends/lib/create/templates/**/package.json', 18 | ], { 19 | absolute: true 20 | } ) 21 | 22 | files.map( file => path.dirname( file ) ) 23 | 24 | console.log() 25 | 26 | await files.reduce( async ( total, file ) => { 27 | await total 28 | 29 | const basedir = path.relative( process.cwd(), path.dirname( file ) ) 30 | 31 | const data = await check( { 32 | path: file, 33 | entries: [], 34 | noDefaultEntries: false, 35 | extensions: [ '.js' ] 36 | } ) 37 | 38 | const pkg = data.package 39 | const deps = data.used 40 | 41 | const missing = check.missing( pkg, deps, { 42 | excludeDev: false, 43 | excludePeer: false, 44 | ignore: [] 45 | } ) 46 | 47 | if ( missing.length ) { 48 | console.error( basedir + ':', chalk.red( 'Fail!' ) +' Dependencies not listed in package.json: ' ) 49 | console.log() 50 | console.log( missing.map( m => chalk.blue.inverse( ' ' + m + ' ' ) ).join( ' ' ) ) 51 | } else { 52 | console.log( basedir + ':', chalk.green( 'Passed' ) ) 53 | } 54 | 55 | console.log() 56 | }, Promise.resolve() ) 57 | } )() 58 | -------------------------------------------------------------------------------- /templates/pages/index.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const path = require( 'path' ) 4 | const sao = require( 'sao' ) 5 | const cac = require( 'cac' ) 6 | const pkg = require( './package.json' ) 7 | const cli = cac() 8 | 9 | cli 10 | .command( '[dir]', 'Generate a new project to target folder' ) 11 | .action( async ( dir ) => { 12 | const outDir = path.join( process.cwd(), dir || './' ) 13 | 14 | const saoGenerator = sao( { 15 | generator: __dirname, 16 | outDir, 17 | updateCheck: true, 18 | logLevel: 3 19 | } ) 20 | 21 | await saoGenerator.run().catch( sao.handleError ) 22 | } ) 23 | 24 | cli.version( pkg.version ) 25 | cli.help() 26 | cli.parse() 27 | -------------------------------------------------------------------------------- /templates/pages/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "create-nut-pages", 3 | "version": "1.0.0-alpha.8", 4 | "publishConfig": { 5 | "access": "public" 6 | }, 7 | "description": "scaffold for nut pages", 8 | "keywords": [ 9 | "nut", 10 | "pages" 11 | ], 12 | "main": "index.js", 13 | "bin": { 14 | "create-nut-pages": "./index.js" 15 | }, 16 | "engines": { 17 | "node": ">=8.9.0" 18 | }, 19 | "repository": "https://github.com/nut-project/nut/tree/master/templates/pages", 20 | "homepage": "http://nut.js.org", 21 | "bugs": { 22 | "url": "https://github.com/nut-project/nut/issues/new/choose" 23 | }, 24 | "scripts": {}, 25 | "author": { 26 | "name": "fengzilong", 27 | "email": "fengzilong1992@gmail.com", 28 | "url": "https://github.com/fengzilong" 29 | }, 30 | "license": "MIT", 31 | "dependencies": { 32 | "cac": "^6.5.3", 33 | "jstransformer-handlebars": "^1.1.0", 34 | "sao": "^1.7.0" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /templates/pages/saofile.js: -------------------------------------------------------------------------------- 1 | const path = require( 'path' ) 2 | 3 | module.exports = { 4 | transformer: 'handlebars', 5 | 6 | templateData: { 7 | }, 8 | 9 | prompts() { 10 | return [ 11 | { 12 | name: 'name', 13 | message: 'What is the name of the new project', 14 | default: this.outFolder, 15 | filter: val => val.toLowerCase() 16 | }, 17 | { 18 | name: 'description', 19 | message: 'How would you descripe the new project', 20 | default: `my awesome nut project` 21 | }, 22 | { 23 | name: 'username', 24 | message: 'What is your username', 25 | default: this.gitUser.username || this.gitUser.name, 26 | filter: val => val.toLowerCase(), 27 | store: true 28 | }, 29 | { 30 | name: 'email', 31 | message: 'What is your email?', 32 | default: this.gitUser.email, 33 | store: true 34 | }, 35 | 36 | // nut.config.js 37 | { 38 | name: 'zh', 39 | message: 'Name of your application in Chinese', 40 | default: '应用名', 41 | }, 42 | ] 43 | }, 44 | 45 | actions: [ 46 | { 47 | type: 'add', 48 | files: '**', 49 | }, 50 | ], 51 | 52 | async completed() { 53 | await this.gitInit() 54 | 55 | // const pkgPath = path.join( this.outDir, 'package.json' ) 56 | // if ( await this.fs.pathExists( pkgPath ) ) { 57 | // await this.npmInstall() 58 | // } 59 | 60 | this.showProjectTips() 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /templates/pages/template/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | 3 | # Logs 4 | logs 5 | *.log 6 | npm-debug.log* 7 | yarn-debug.log* 8 | yarn-error.log* 9 | 10 | # Runtime data 11 | pids 12 | *.pid 13 | *.seed 14 | *.pid.lock 15 | 16 | # Directory for instrumented libs generated by jscoverage/JSCover 17 | lib-cov 18 | 19 | # Coverage directory used by tools like istanbul 20 | coverage 21 | 22 | # nyc test coverage 23 | .nyc_output 24 | 25 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 26 | .grunt 27 | 28 | # Bower dependency directory (https://bower.io/) 29 | bower_components 30 | 31 | # node-waf configuration 32 | .lock-wscript 33 | 34 | # Compiled binary addons (https://nodejs.org/api/addons.html) 35 | build/Release 36 | 37 | # Dependency directories 38 | node_modules/ 39 | jspm_packages/ 40 | 41 | # TypeScript v1 declaration files 42 | typings/ 43 | 44 | # Optional npm cache directory 45 | .npm 46 | 47 | # Optional eslint cache 48 | .eslintcache 49 | 50 | # Optional REPL history 51 | .node_repl_history 52 | 53 | # Output of 'npm pack' 54 | *.tgz 55 | 56 | # Yarn Integrity file 57 | .yarn-integrity 58 | 59 | # dotenv environment variables file 60 | .env 61 | 62 | # next.js build output 63 | .next 64 | -------------------------------------------------------------------------------- /templates/pages/template/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "{{ name }}", 3 | "private": true, 4 | "version": "0.0.0", 5 | "description": "{{ description }}", 6 | "keywords": [], 7 | "scripts": { 8 | "dev": "nut pages dev", 9 | "build": "nut pages build" 10 | }, 11 | "author": { 12 | {{#if username}}"name": "{{ username }}"{{/if}}{{#if email}}, 13 | "email": "{{ email }}"{{/if}} 14 | }, 15 | "devDependencies": { 16 | "@nut-project/cli": "^1.0.0", 17 | "@nut-plugins/pages-microfrontends": "^1.0.0", 18 | "@nut-plugins/pages-layout-now": "^1.0.0" 19 | }, 20 | "license": "MIT" 21 | } 22 | -------------------------------------------------------------------------------- /templates/pages/template/pages.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | zh: '{{ zh }}', 3 | layout: 'now', 4 | markdown: { 5 | theme: 'prism-duotone-light', 6 | }, 7 | plugins: [ 8 | '@nut-plugins/pages-microfrontends', 9 | '@nut-plugins/pages-layout-now', 10 | ], 11 | sidebar: [ 12 | { 13 | title: 'Menu', 14 | children: [ 15 | { title: 'demo', path: 'pages/demo' }, 16 | { title: 'markdown', path: 'pages/markdown' }, 17 | ] 18 | } 19 | ], 20 | homepage: 'pages/home', 21 | } 22 | -------------------------------------------------------------------------------- /templates/pages/template/src/app.js: -------------------------------------------------------------------------------- 1 | export default ctx => { 2 | // 定制 pages/home 布局为 none 3 | ctx.api.page( 'pages/home' ).set( 'layout', 'none' ) 4 | } 5 | -------------------------------------------------------------------------------- /templates/pages/template/src/pages/demo.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | 13 | 15 | -------------------------------------------------------------------------------- /templates/pages/template/src/pages/home.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 21 | 22 | 53 | -------------------------------------------------------------------------------- /templates/pages/template/src/pages/markdown.md: -------------------------------------------------------------------------------- 1 | # Markdown page 2 | 3 | write your **markdown** here 4 | 5 | ```js 6 | function sayHello() { 7 | console.log( 'hello world' ) 8 | } 9 | ``` 10 | -------------------------------------------------------------------------------- /templates/pages/template/src/public/nut-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nut-project/nut/672e123a975dc02ffc12a5bbad31a2c5a49fc776/templates/pages/template/src/public/nut-logo.png -------------------------------------------------------------------------------- /website/.gitignore: -------------------------------------------------------------------------------- 1 | yarn.lock 2 | src/materials 3 | -------------------------------------------------------------------------------- /website/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. 5 | 6 | ## [0.1.1-alpha.1](https://github.com/fengzilong/nut/compare/nut-docs@0.1.1-alpha.0...nut-docs@0.1.1-alpha.1) (2019-10-08) 7 | 8 | **Note:** Version bump only for package nut-docs 9 | 10 | 11 | 12 | 13 | 14 | # [0.1.0](https://github.com/fengzilong/nut/compare/nut-docs@0.0.4...nut-docs@0.1.0) (2019-09-24) 15 | 16 | 17 | ### Features 18 | 19 | * add for vue, fix instantiation of Vue component ([5e1d2f8](https://github.com/fengzilong/nut/commit/5e1d2f8)) 20 | -------------------------------------------------------------------------------- /website/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nut-docs", 3 | "version": "1.0.0-alpha.2", 4 | "private": true, 5 | "scripts": { 6 | "dev": "node ../packages/cli/bin/index.js pages dev", 7 | "build": "node ../packages/cli/bin/index.js pages build", 8 | "create-pages": "node ../packages/cli/bin/index.js pages create demo" 9 | }, 10 | "dependencies": { 11 | "@zeit-ui/themes": "^0.1.0", 12 | "@zeit-ui/vue": "1.3.1", 13 | "vue": ">2.0.0" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /website/pages.config.js: -------------------------------------------------------------------------------- 1 | const path = require( 'path' ) 2 | 3 | function getNowOptions( options = {} ) { 4 | return { 5 | search: { 6 | appId: 'FZANFOBNUT', 7 | apiKey: '8c79ef62f918611dd1dce669466327ca', 8 | indexName: 'nut', 9 | debug: true, 10 | placeholder: '搜索', 11 | ...( options.search || {} ) 12 | }, 13 | navbar: { 14 | width: '200px', 15 | ...( options.navbar || {} ) 16 | }, 17 | editpage: { 18 | base: 'https://github.com/nut-project/nut/tree/master/website/src/', 19 | ...( options.editpage || {} ) 20 | }, 21 | } 22 | } 23 | 24 | const config = { 25 | verbose: false, 26 | port: 9000, 27 | router: { 28 | mode: 'history', 29 | }, 30 | zh: 'nut project', 31 | html: { 32 | title: 'NUT 文档', 33 | template: path.join( __dirname, 'src/index.ejs' ), 34 | }, 35 | logo: '/logo.png', 36 | theme: 'ocean', 37 | layout: 'now', 38 | markdown: { 39 | theme: 'prism-dracula', 40 | remarkPlugins: [], 41 | rehypePlugins: [], 42 | }, 43 | homepage: 'pages/home', 44 | babel: { 45 | transpileModules: [ '@zeit-ui/vue' ] 46 | }, 47 | plugins: [ 48 | path.join( __dirname, './plugins/now-custom' ), 49 | [ 50 | path.join( __dirname, '../plugins/pages/layout-now' ), 51 | process.env.NODE_ENV === 'development' ? 52 | getNowOptions() : 53 | getNowOptions( { search: { debug: false } } ) 54 | ], 55 | [ 56 | path.join( __dirname, '../plugins/pages/materials' ), 57 | { url: `https://ice.alicdn.com/assets/materials/vue-materials.json` } 58 | ], 59 | path.join( __dirname, '../plugins/pages/layout-kaola' ), 60 | path.join( __dirname, '../plugins/pages/layout-kaola' ), 61 | path.join( __dirname, '../plugins/pages/layout-side' ), 62 | path.join( __dirname, '../plugins/pages/layout-saber' ), 63 | path.join( __dirname, '../plugins/pages/microfrontends' ), 64 | ] 65 | } 66 | 67 | if ( process.env.NODE_ENV === 'production' ) { 68 | config.output = { 69 | publicPath: 'https://nut.js.org/' 70 | } 71 | } 72 | 73 | module.exports = config 74 | -------------------------------------------------------------------------------- /website/plugins/now-custom/index.js: -------------------------------------------------------------------------------- 1 | const path = require( 'path' ) 2 | 3 | exports.name = 'layout-now-custom' 4 | exports.apply = api => { 5 | api.addRuntimeModule( { 6 | file: path.join( __dirname, './runtime.js' ), 7 | } ) 8 | } 9 | -------------------------------------------------------------------------------- /website/search.config.js: -------------------------------------------------------------------------------- 1 | { 2 | "index_name": "nut", 3 | "start_urls": [ 4 | "http://nut.js.org" 5 | ], 6 | "scrape_start_urls": false, 7 | "js_render": true, 8 | "selectors": { 9 | "lvl0": { 10 | "selector": ".nut-layout-now2-lvl0", 11 | "global": true 12 | }, 13 | "lvl1": { 14 | "selector": ".nut-layout-now2-lvl1", 15 | "global": true 16 | }, 17 | "lvl2": ".nut-layout-now2-content h2", 18 | "lvl3": ".nut-layout-now2-content h3", 19 | "lvl4": ".nut-layout-now2-content h4", 20 | "lvl5": ".nut-layout-now2-content h5", 21 | "text": ".nut-layout-now2-content p, .nut-layout-now2-content li, .nut-layout-now2-content .zi-note, .nut-layout-now2-content code, .nut-layout-now2-content a" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /website/src/index.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | <%= htmlWebpackPlugin.options.title %> 8 | 9 | 10 | 11 | 14 | 20 |
21 | 22 | 23 | -------------------------------------------------------------------------------- /website/src/pages/docs/api.md: -------------------------------------------------------------------------------- 1 | #### axios 2 | 3 | ```js 4 | ctx.axios.get 5 | ctx.axios.post 6 | ``` 7 | 8 | 更多用法请参考 [axios](https://github.com/axios/axios) 9 | 10 | #### layout.register 11 | 12 | 注册一个新的 layout,一般使用于插件内部 13 | 14 | ```js 15 | await ctx.api.layout.register( { 16 | name: 'layout-name', 17 | mount( node, { ctx } ) {}, 18 | unmount( node ) {}, 19 | update( data = {} ) {}, 20 | getMountNode() {} 21 | } ) 22 | ``` 23 | 24 | #### homepage.set 25 | 26 | 配置首页,可以认为是设置 `/` 的别名路由 27 | 28 | ```js 29 | ctx.api.homepage.set( 'pages/home' ) 30 | ``` 31 | 32 | #### page 33 | 34 | 配置页面的基本属性,常见的比如 cacheable、layout 35 | 36 | ```js 37 | ctx.page( 'pages/foo' ).get( 'key' ) 38 | ctx.page( 'pages/foo' ).set( 'cacheable', false ) 39 | ctx.page( 'pages/foo' ).set( 'layout', 'none' ) 40 | ``` 41 | 42 | #### router.format 43 | 44 | 路由解析 45 | 46 | ```js 47 | ctx.api.router.format( { 48 | page: 'pages/foo/_id', 49 | query: { key: 'value' }, 50 | params: { id: '123' } 51 | } ) 52 | 53 | // -> /pages/foo/123?key=value 54 | ``` 55 | 56 | #### router.push 57 | 58 | 路由跳转 59 | 60 | ```js 61 | ctx.api.router.push( { 62 | page: 'pages/foo/_id', 63 | query: { key: 'value' }, 64 | params: { id: '123' } 65 | } ) 66 | 67 | // -> 跳转至新路由 /pages/foo/123?key=value 68 | ``` 69 | 70 | #### router.replace 71 | 72 | 路由跳转,类似 push,但是会覆盖当前路由 73 | 74 | ```js 75 | ctx.api.router.replace( { 76 | page: 'pages/foo/_id', 77 | query: { key: 'value' }, 78 | params: { id: '123' } 79 | } ) 80 | 81 | // -> 跳转至新路由 /pages/foo/123?key=value 82 | ``` 83 | 84 | #### sidebar.get 85 | 86 | 获取 sidebar 87 | 88 | ```js 89 | ctx.sidebar.get() 90 | ``` 91 | 92 | #### sidebar.configure 93 | 94 | 配置 sidebar 95 | 96 | ```js 97 | ctx.sidebar.configure( [ 98 | { 99 | title: 'hello', 100 | icon: '', 101 | children: [ 102 | { title: '标题', page: 'pages/hello' } 103 | ], 104 | }, 105 | { 106 | title: 'world', 107 | link: 'https://github.com' 108 | } 109 | ] ) 110 | ``` 111 | -------------------------------------------------------------------------------- /website/src/pages/docs/cli.md: -------------------------------------------------------------------------------- 1 | ### 常用命令 2 | 3 | | 字段 | 说明 | 4 | | ---------- | ----------------------------:| 5 | | nut | 开发模式,默认监听 9000 端口 | 6 | | nut --prod | 构建生产输出 | 7 | 8 | 只要记住这两个命令就够啦,很简单吧 😉 9 | -------------------------------------------------------------------------------- /website/src/pages/docs/router.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nut-project/nut/672e123a975dc02ffc12a5bbad31a2c5a49fc776/website/src/pages/docs/router.md -------------------------------------------------------------------------------- /website/src/pages/guide/css-modules.vue.md: -------------------------------------------------------------------------------- 1 | nut 默认支持 CSS Modules 2 | 3 | 使用 `.module.[extension]` 后缀,即可开启 CSS Modules 特性 4 | 5 | ## 举例 6 | 7 | | 后缀 | css modules 后缀 | 8 | | ------- | ----------------:| 9 | | .css | .module.css | 10 | | .less | .module.less | 11 | | .scss | .module.scss | 12 | | .sass | .module.sass | 13 | | .styl | .module.styl | 14 | | .stylus | .module.stylus | 15 | 16 | ## 相关资料 17 | 18 | CSS Modules 19 | -------------------------------------------------------------------------------- /website/src/pages/guide/css-preprocessor.vue.md: -------------------------------------------------------------------------------- 1 | nut 内置的 CSS 预处理器如下 2 | 3 | | 预处理器 | 后缀 | 4 | | -------- | ---------------:| 5 | | less | .less | 6 | | scss | .scss | 7 | | sass | .sass | 8 | | stylus | .styl / .stylus | 9 | 10 | 如果需要支持新的 css 预处理器,欢迎提 issue 11 | -------------------------------------------------------------------------------- /website/src/pages/guide/experience.md: -------------------------------------------------------------------------------- 1 | 你可以在 Gitpod 中体验 nut 2 | 3 | [![Open in Gitpod](/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/fengzilong/nut-example) 4 | -------------------------------------------------------------------------------- /website/src/pages/guide/installation.md: -------------------------------------------------------------------------------- 1 | ## 环境要求 2 | 3 | ``` 4 | node >= 8.9.0 5 | ``` 6 | 7 | ## 安装 8 | 9 | ```bash 10 | yarn add @nut-project/cli 11 | ``` 12 | -------------------------------------------------------------------------------- /website/src/pages/guide/layout.vue.md: -------------------------------------------------------------------------------- 1 | ## 内置布局 2 | 3 | nut 内置了以下几套布局 4 | 5 | - default 6 | - saber 7 | - now 8 | - kaola 9 | - none 10 | 11 | ## 全局布局 12 | 13 | 你可以在 `nut.config.js` 中通过 `layout` 声明全局布局,如果页面未声明自己的 layout,就会降级到 全局主题 14 | 15 | ## 页面布局 16 | 17 | 如何定制某个页面的布局呢? 18 | 19 | 很简单,在 `src/app.js` 中 20 | 21 | ```js 22 | export default ctx => { 23 | ctx.api.page( 'pages/path' ).set( 'layout', 'layout-name' ) 24 | } 25 | ``` 26 | 27 | 每个页面的布局都可以不同,当然大部分情况下你不需要这么花里胡哨 28 | 29 | 30 | 比较常用的是 none 这个特殊布局,none 布局几乎没有任何内容,相当于一个“空的画板”,你可以在这个基础上定制你的页面内容 31 | 32 | 33 | ## 如何实现新布局 34 | 35 | 在 nut 中,你可以通过写一个插件来注册一个新的布局(插件的基本写法请参见插件章节) 36 | 37 | 涉及的 API:`ctx.api.layout.register` 38 | 39 | ```js 40 | ctx.api.layout.register( { 41 | name: 'your-layout-name', // 布局名称,用户使用该布局时需要用到 42 | mount( node ) {}, // 挂载时调用 43 | unmount( node ) {}, // 卸载时调用 44 | update( data ) {}, // 热重载时调用 45 | getMountNode() {}, // 页面挂载点,需返回一个 DOM 节点的引用 46 | } ) 47 | ``` 48 | 49 | 如果是通用的布局,你可以将该布局插件发布到 npm 上和组内的成员进行共享 50 | -------------------------------------------------------------------------------- /website/src/pages/guide/markdown.vue.md: -------------------------------------------------------------------------------- 1 | nut 会自动识别 `src/pages` 目录下的 `.md` 文件,转换成路由,你可以将该路由放入 { this.$ctx.api.router.push( '/pages/docs/config' ) } 3 | } more>配置文件 的 sidebar 字段中,nut 会帮你自动生成菜单 4 | 5 | ## 默认高亮主题 6 | 7 | `prism-tomorrow` 8 | 9 | ## 所有高亮主题 10 | 11 | | 主题 | 预览 | 12 | | ------------------------------------- | ----:| 13 | | prism | - | 14 | | prism-okaidia | - | 15 | | prism-solarizedlight | - | 16 | | prism-tomorrow | - | 17 | | prism-twilight | - | 18 | | prism-a11y-dark | | 19 | | prism-atom-dark | | 20 | | prism-base16-ateliersulphurpool.light | | 21 | | prism-cb | | 22 | | prism-darcula | | 23 | | prism-duotone-dark | | 24 | | prism-duotone-earth | | 25 | | prism-duotone-forest | | 26 | | prism-duotone-light | | 27 | | prism-duotone-sea | | 28 | | prism-duotone-space | | 29 | | prism-ghcolors | | 30 | | prism-hopscotch | | 31 | | prism-pojoaque | | 32 | | prism-vs | | 33 | | prism-xonokai | | 34 | | prism-dracula | | 35 | -------------------------------------------------------------------------------- /website/src/pages/guide/microfrontends.vue.md: -------------------------------------------------------------------------------- 1 | 2 |

合成来源:

3 | http://nut.js.org 4 |
5 | http://fengzilong.github.io/nut-todomvc-example/ 6 | 7 | 15 |
16 | -------------------------------------------------------------------------------- /website/src/pages/guide/plugin.md: -------------------------------------------------------------------------------- 1 | ## 插件 2 | 3 | 🚧 4 | -------------------------------------------------------------------------------- /website/src/pages/guide/public.vue.md: -------------------------------------------------------------------------------- 1 | nut 默认使用 `src/public` 作为静态目录 2 | 3 | ## 示例 4 | 5 | 22 | 23 | ↓ 打包后 ↓ 24 | 25 | 38 | 39 | ## 如何引用 pulic 下的文件 40 | 41 | ``` 42 | ${ publicUrl }sample.jpg 43 | ${ publicUrl }font.woff2 44 | ``` 45 | 46 | 47 | publicUrl 根据实际情况替换 48 | 49 | -------------------------------------------------------------------------------- /website/src/pages/guide/quicklink.vue.md: -------------------------------------------------------------------------------- 1 | nut 内部使用 quicklink 对加载做了优化 2 | 3 | ## 对比 4 | 5 | | 未使用 quicklink | 使用 quicklink | 6 | | :---: | :---: | 7 | | ![no-quicklink](/no-quicklink.gif) | ![quicklink](/quicklink.gif) | 8 | 9 | ## API 10 | 11 | `ctx.api.quicklink.prefetch` 12 | 13 | **举例** 14 | 15 | ```js 16 | ctx.api.quicklink.prefetch( [ 17 | 'pages/foo', 18 | 'pages/bar' 19 | ] ) 20 | ``` 21 | -------------------------------------------------------------------------------- /website/src/pages/guide/theme.vue.md: -------------------------------------------------------------------------------- 1 | nut 支持不同的配色方案 2 | 3 | 目前内置了两套主题,分别为 ocean、sakura 4 | -------------------------------------------------------------------------------- /website/src/pages/home.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 44 | 45 | 80 | -------------------------------------------------------------------------------- /website/src/public/CNAME: -------------------------------------------------------------------------------- 1 | nut.js.org 2 | -------------------------------------------------------------------------------- /website/src/public/_redirects: -------------------------------------------------------------------------------- 1 | /* /index.html 200 2 | -------------------------------------------------------------------------------- /website/src/public/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nut-project/nut/672e123a975dc02ffc12a5bbad31a2c5a49fc776/website/src/public/logo.png -------------------------------------------------------------------------------- /website/src/public/no-quicklink.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nut-project/nut/672e123a975dc02ffc12a5bbad31a2c5a49fc776/website/src/public/no-quicklink.gif -------------------------------------------------------------------------------- /website/src/public/open-in-gitpod.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | in Gitpod 7 | 8 | 9 | Open 10 | 11 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /website/src/public/quicklink.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nut-project/nut/672e123a975dc02ffc12a5bbad31a2c5a49fc776/website/src/public/quicklink.gif -------------------------------------------------------------------------------- /website/src/public/social-media-preview-750.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nut-project/nut/672e123a975dc02ffc12a5bbad31a2c5a49fc776/website/src/public/social-media-preview-750.png -------------------------------------------------------------------------------- /website/src/public/social-media-preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nut-project/nut/672e123a975dc02ffc12a5bbad31a2c5a49fc776/website/src/public/social-media-preview.png -------------------------------------------------------------------------------- /website/src/public/terminal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nut-project/nut/672e123a975dc02ffc12a5bbad31a2c5a49fc776/website/src/public/terminal.png -------------------------------------------------------------------------------- /website/src/public/website-screenshot-nut.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nut-project/nut/672e123a975dc02ffc12a5bbad31a2c5a49fc776/website/src/public/website-screenshot-nut.jpg -------------------------------------------------------------------------------- /website/src/public/website-screenshot-todomvc.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nut-project/nut/672e123a975dc02ffc12a5bbad31a2c5a49fc776/website/src/public/website-screenshot-todomvc.jpg --------------------------------------------------------------------------------