-1?Zn[t]=e.constructor===window.HTMLUnknownElement||e.constructor===window.HTMLElement:Zn[t]=/HTMLUnknownElement/.test(e.toString())},k(wn.options.directives,go),k(wn.options.components,Bo),wn.prototype.__patch__=z?co:j,wn.prototype.$mount=function(t,e){return function(t,e,n){var r;return t.$el=e,t.$options.render||(t.$options.render=pt),tn(t,"beforeMount"),r=function(){t._update(t._render(),n)},new pn(t,r,j,{before:function(){t._isMounted&&!t._isDestroyed&&tn(t,"beforeUpdate")}},!0),n=!1,null==t.$vnode&&(t._isMounted=!0,tn(t,"mounted")),t}(this,t=t&&z?function(t){return"string"==typeof t?document.querySelector(t)||document.createElement("div"):t}(t):void 0,e)},z&&setTimeout((function(){D.devtools&&et&&et.emit("init",wn)}),0);const Lo=wn;var No=function(){var t=this,e=t.$createElement,n=t._self._c||e;return t.show?n("div",{staticClass:"App"},[n("header",{staticClass:"App-header"},[n("img",{staticClass:"App-logo",attrs:{src:t.logo,alt:"logo"}}),t._v(" "),n("span",{staticClass:"App-close-icon",on:{click:t.handleClose}},[t._v("\n ×\n ")]),t._v(" "),t._m(0),t._v(" "),n("a",{staticClass:"App-link",attrs:{href:"https://reactjs.org",target:"_blank",rel:"noopener noreferrer"}},[t._v("\n Learn Wokoo\n ")])])]):n("div",{staticClass:"App-hide",on:{click:t.handleClose}},[n("img",{staticClass:"App-hide-logo",attrs:{src:t.logo,alt:"logo"}}),t._v("\n open\n")])};No._withStripped=!0;var To=n(379),Po=n.n(To),Qo=n(31);Po()(Qo.Z,{insert:"head",singleton:!1}),Qo.Z.locals;var Do=function(t,e,n,r,o,i,a,s){var c,u="function"==typeof t?t.options:t;if(e&&(u.render=e,u.staticRenderFns=[function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("p",[t._v("\n Edit "),n("code",[t._v("App.vue")]),t._v(" and save to reload.\n ")])}],u._compiled=!0),u._scopeId="data-v-5ef48958",c)if(u.functional){u._injectStyles=c;var l=u.render;u.render=function(t,e){return c.call(e),l(t,e)}}else{var f=u.beforeCreate;u.beforeCreate=f?[].concat(f,c):[c]}return{exports:t,options:u}}({data:function(){return{logo:"data:image/jpeg;base64,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",show:!0}},methods:{handleClose(){this.show=!this.show}}},No);Do.options.__file="src/app.vue";const Fo=Do.exports,Ro=document.createElement("div");Ro.id="wokoonApp",document.body.appendChild(Ro),new Lo({el:"#wokoonApp",render:t=>t(Fo)})})()})();
3 | //# sourceMappingURL=app.bundle.js.map
--------------------------------------------------------------------------------
/example/wokoo-demo/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "d",
3 | "version": "0.0.1",
4 | "private": true,
5 | "scripts": {
6 | "start": "cross-env NODE_ENV=development webpack-dev-server",
7 | "build": "webpack"
8 | },
9 | "dependencies": {
10 | "vue": "2.6.12",
11 | "vue-template-compiler": "2.6.12"
12 | },
13 | "devDependencies": {
14 | "cross-env": "7.0.3",
15 | "css-loader": "5.0.1",
16 | "file-loader": "6.2.0",
17 | "html-webpack-plugin": "4.5.1",
18 | "less": "4.1.0",
19 | "less-loader": "7.2.1",
20 | "style-loader": "2.0.0",
21 | "url-loader": "4.1.1",
22 | "vue-loader": "15.9.6",
23 | "webpack": "5.15.0",
24 | "webpack-cli": "3.3.12",
25 | "webpack-dev-server": "3.11.2",
26 | "webpack-merge": "5.7.3"
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/example/wokoo-demo/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kinyaying/wokoo/2961afcb53c0e85dae8ec0f93b6f73fb0c9eb134/example/wokoo-demo/public/favicon.ico
--------------------------------------------------------------------------------
/example/wokoo-demo/public/icon.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kinyaying/wokoo/2961afcb53c0e85dae8ec0f93b6f73fb0c9eb134/example/wokoo-demo/public/icon.jpg
--------------------------------------------------------------------------------
/example/wokoo-demo/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/example/wokoo-demo/src/app.less:
--------------------------------------------------------------------------------
1 | .App {
2 | position: absolute;
3 | text-align: center;
4 | width: 400px;
5 | height: 400px;
6 | top: 0;
7 | right: 0;
8 | z-index: 999;
9 | }
10 | .App-logo {
11 | height: 30vmin;
12 | border-radius: 50%;
13 | pointer-events: none;
14 | }
15 | @media (prefers-reduced-motion: no-preference) {
16 | .App-logo {
17 | animation: App-logo-spin infinite 20s linear;
18 | }
19 | }
20 |
21 | .App-header {
22 | background-color: #6c4d25;
23 | display: flex;
24 | flex-direction: column;
25 | align-items: center;
26 | justify-content: center;
27 | font-size: calc(10px + 2vmin);
28 | color: white;
29 | height: 100%;
30 | }
31 |
32 | .App-link {
33 | color: #efb61c;
34 | }
35 | .App-close-icon {
36 | position: absolute;
37 | top: 0;
38 | right: 10px;
39 | font-size: 30px;
40 | cursor: pointer;
41 | }
42 | .App-hide {
43 | position: absolute;
44 | text-align: center;
45 | width: 100px;
46 | height: 40px;
47 | background-color: #6c4d25;
48 | top: 0;
49 | right: 0;
50 | z-index: 999;
51 | display: flex;
52 | align-items: center;
53 | justify-content: center;
54 | color: #fff;
55 | cursor: pointer;
56 | }
57 | .App-hide-logo {
58 | width: 30px;
59 | height: 30px;
60 | border-radius: 50%;
61 | margin-right: 10px;
62 | }
63 |
64 | @keyframes App-logo-spin {
65 | from {
66 | transform: rotate(0deg);
67 | }
68 | to {
69 | transform: rotate(360deg);
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/example/wokoo-demo/src/app.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
23 |
24 |
25 |
![logo]()
26 | open
27 |
28 |
29 |
46 |
48 |
--------------------------------------------------------------------------------
/example/wokoo-demo/src/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './app.vue'
3 |
4 | const root = document.createElement('div')
5 | root.id = 'wokooApp'
6 | document.body.appendChild(root)
7 | const vm = new Vue({
8 | el: '#wokooApp',
9 | render: (h) => h(App),
10 | })
11 |
--------------------------------------------------------------------------------
/example/wokoo-demo/tampermonkey.txt:
--------------------------------------------------------------------------------
1 | // ==UserScript==
2 | // @name wokoo-demo
3 | // @namespace http://tampermonkey.net/
4 | // @version 0.0.1
5 | // @description try to take over the world!
6 | // @author kinyaying
7 | // @match https://*/*
8 | // @match http://*/*
9 |
10 |
11 | // ==/UserScript==
12 |
13 | (function() {
14 | 'use strict';
15 | if(location.href === "http://localhost:8080/") return
16 | let script = document.createElement('script')
17 | script.src='http://localhost:8080/app.bundle.js'
18 | document.body.appendChild(script)
19 |
20 | })();
--------------------------------------------------------------------------------
/example/wokoo-demo/webpack.config.base.js:
--------------------------------------------------------------------------------
1 | const VueLoaderPlugin = require('vue-loader/lib/plugin')
2 |
3 | module.exports = {
4 | entry: {
5 | app: '/src/index.js',
6 | },
7 | module: {
8 | rules: [
9 | {
10 | test: /\.vue$/,
11 | loader: 'vue-loader',
12 | },
13 | ],
14 | },
15 | plugins: [new VueLoaderPlugin()],
16 | }
17 |
--------------------------------------------------------------------------------
/example/wokoo-demo/webpack.config.js:
--------------------------------------------------------------------------------
1 | const HtmlWebpackPlugin = require('html-webpack-plugin')
2 | const { merge } = require('webpack-merge')
3 | const base = require('./webpack.config.base')
4 |
5 | module.exports = merge(base, {
6 | mode: process.env.NODE_ENV || 'production',
7 | devtool: 'source-map',
8 | output: {
9 | filename: '[name].bundle.js',
10 | path: __dirname + '/dist',
11 | },
12 | module: {
13 | rules: [
14 | {
15 | test: /\.(less|css)$/,
16 | use: ['style-loader', 'css-loader', 'less-loader'],
17 | },
18 | {
19 | test: /\.(woff|woff2|eot|ttf|otf|png|svg|jpg|gif)$/,
20 | use: {
21 | loader: 'url-loader',
22 | options: {
23 | limit: 20480,
24 | },
25 | },
26 | },
27 | ],
28 | },
29 | plugins: [
30 | new HtmlWebpackPlugin({
31 | template: './public/index.html',
32 | }),
33 | ],
34 | })
35 |
--------------------------------------------------------------------------------
/example/zhihu-helper/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/example/zhihu-helper/README.md:
--------------------------------------------------------------------------------
1 | ## zhihu-helper
2 |
3 | 基于 wokoo 搭建的初始化工程,用于油猴插件开发。
4 |
5 | **基础配置:**
6 |
7 | - react
8 | - less
9 | - webpack
10 |
11 | ## 目录结构
12 |
13 | ```
14 | .
15 | ├── README.md 说明
16 | ├── package-lock.json
17 | ├── package.json
18 | ├── public 静态文件
19 | │ ├── favicon.ico
20 | │ ├── icon.jpg
21 | │ └── index.html html 文件
22 | ├── src
23 | │ ├── app.less
24 | │ ├── app.js
25 | │ └── index.js 项目入口
26 | ├── tampermonkey.txt 油猴脚本入口文件
27 | ├── webpack.config.base.js
28 | └── webpack.config.js webpack 配置
29 | ```
30 |
31 | ## 开发
32 |
33 | **启动**
34 | 进入项目目录后,在命令行中输入:
35 |
36 | ```shell
37 | npm start
38 | ```
39 |
40 | **调试**
41 |
42 | 1. 打开浏览器,输入`localhost:8080`,查看页面展示是否正常。
43 | 2. 安装油猴插件
44 | 3. 打开油猴插件编辑界面,将 tampermonkey.txt 里的内容复制到编辑框中,保存。
45 | 4. 打开任意一个网页,比如`www.baidu.com`,
46 |
47 | - 查看油猴 icon 是否有一个 1 的数字标志,如果有说明油猴脚本已经成功激活
48 | - 网页的右上角会出现初始页面
49 |
50 | **构建**
51 |
52 | ```shell
53 | npm run build
54 | ```
55 |
56 | **发布插件到油猴市场**
57 |
58 | 油猴市场的优点是不用审核,即发即用,非常方便。
59 |
60 | 1. 将/dist/app.bundle.js 文件部署到 cdn 上,获取到对应 url。(可以放到 github 上,如果托管到 git 上最好做 cdn 加速)
61 | 2. 登录[油猴市场](https://greasyfork.org/),谷歌账号或 github 账号都可使用。
62 | 3. 点击账号名称,再点击**发布你编写的脚本**
63 | 4. 进入编辑页,将 tampermonkey.txt 里的内容复制到编辑框中,记得将里面的`localhost:8080`网址替换成静态资源 url
64 | 5. 点击 「发布脚本」即可
65 |
66 | ## 例子 demo
67 |
68 | 我已经使用 wokoo 脚手架开发了多个 demo,并发布到[油猴市场](https://greasyfork.org/),欢迎安装试用。
69 | [wokoo-demo](https://greasyfork.org/zh-CN/scripts/420327-wokoo-demo): 简单的示例插件
70 |
71 | ## 了解更多
72 |
73 | 如果想了解更多内容,请访问下面的网址:
74 | [油猴脚手架 wokoo 使用说明](https://juejin.cn/post/6922815205575491597)
75 | [油猴脚手架 wokoo git 仓库](https://github.com/kinyaying/wokoo)
76 |
--------------------------------------------------------------------------------
/example/zhihu-helper/dist/app.bundle.js.LICENSE.txt:
--------------------------------------------------------------------------------
1 | /*
2 | object-assign
3 | (c) Sindre Sorhus
4 | @license MIT
5 | */
6 |
7 | /** @license React v0.20.1
8 | * scheduler.production.min.js
9 | *
10 | * Copyright (c) Facebook, Inc. and its affiliates.
11 | *
12 | * This source code is licensed under the MIT license found in the
13 | * LICENSE file in the root directory of this source tree.
14 | */
15 |
16 | /** @license React v16.14.0
17 | * react.production.min.js
18 | *
19 | * Copyright (c) Facebook, Inc. and its affiliates.
20 | *
21 | * This source code is licensed under the MIT license found in the
22 | * LICENSE file in the root directory of this source tree.
23 | */
24 |
25 | /** @license React v17.0.1
26 | * react-dom.production.min.js
27 | *
28 | * Copyright (c) Facebook, Inc. and its affiliates.
29 | *
30 | * This source code is licensed under the MIT license found in the
31 | * LICENSE file in the root directory of this source tree.
32 | */
33 |
--------------------------------------------------------------------------------
/example/zhihu-helper/dist/index.html:
--------------------------------------------------------------------------------
1 | Document
--------------------------------------------------------------------------------
/example/zhihu-helper/dist/vendor.bundle.js.LICENSE.txt:
--------------------------------------------------------------------------------
1 | /*
2 | object-assign
3 | (c) Sindre Sorhus
4 | @license MIT
5 | */
6 |
7 | /** @license React v0.20.1
8 | * scheduler.production.min.js
9 | *
10 | * Copyright (c) Facebook, Inc. and its affiliates.
11 | *
12 | * This source code is licensed under the MIT license found in the
13 | * LICENSE file in the root directory of this source tree.
14 | */
15 |
16 | /** @license React v16.14.0
17 | * react.production.min.js
18 | *
19 | * Copyright (c) Facebook, Inc. and its affiliates.
20 | *
21 | * This source code is licensed under the MIT license found in the
22 | * LICENSE file in the root directory of this source tree.
23 | */
24 |
25 | /** @license React v17.0.1
26 | * react-dom.production.min.js
27 | *
28 | * Copyright (c) Facebook, Inc. and its affiliates.
29 | *
30 | * This source code is licensed under the MIT license found in the
31 | * LICENSE file in the root directory of this source tree.
32 | */
33 |
--------------------------------------------------------------------------------
/example/zhihu-helper/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "zhihu-helper",
3 | "version": "0.0.1",
4 | "private": true,
5 | "scripts": {
6 | "start": "cross-env NODE_ENV=development webpack-dev-server",
7 | "build": "webpack"
8 | },
9 | "dependencies": {
10 | "@babel/core": "7.12.10",
11 | "@babel/plugin-transform-runtime": "^7.12.13",
12 | "@babel/preset-react": "7.12.10",
13 | "axios": "^0.21.1",
14 | "babel-loader": "8.2.2",
15 | "react": "16.14.0",
16 | "react-dom": "17.0.1",
17 | "react-infinite-scroll-component": "^5.1.0"
18 | },
19 | "devDependencies": {
20 | "@babel/plugin-proposal-class-properties": "^7.12.1",
21 | "@babel/plugin-proposal-decorators": "^7.12.12",
22 | "@babel/preset-env": "^7.12.11",
23 | "babel-plugin-transform-runtime": "^6.23.0",
24 | "cross-env": "7.0.3",
25 | "css-loader": "5.0.1",
26 | "file-loader": "6.2.0",
27 | "html-webpack-plugin": "4.5.1",
28 | "less": "4.1.0",
29 | "less-loader": "7.3.0",
30 | "style-loader": "2.0.0",
31 | "url-loader": "4.1.1",
32 | "webpack": "5.19.0",
33 | "webpack-cli": "3.3.12",
34 | "webpack-dev-server": "3.11.2",
35 | "webpack-merge": "5.7.3"
36 | }
37 | }
--------------------------------------------------------------------------------
/example/zhihu-helper/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kinyaying/wokoo/2961afcb53c0e85dae8ec0f93b6f73fb0c9eb134/example/zhihu-helper/public/favicon.ico
--------------------------------------------------------------------------------
/example/zhihu-helper/public/icon.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kinyaying/wokoo/2961afcb53c0e85dae8ec0f93b6f73fb0c9eb134/example/zhihu-helper/public/icon.jpg
--------------------------------------------------------------------------------
/example/zhihu-helper/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/example/zhihu-helper/src/app.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import axios from 'axios'
3 | import InfiniteScroll from 'react-infinite-scroll-component'
4 | import './app.less'
5 |
6 | const limit = 20
7 | export default class extends React.Component {
8 | constructor(props) {
9 | super(props)
10 | this.state = {
11 | show: false,
12 | list: [],
13 | offset: 0,
14 | hasMore: true,
15 | }
16 | this.queryName = null
17 | }
18 | handleShow = () => {
19 | this.setState({
20 | show: !this.state.show,
21 | })
22 | }
23 | handleMouseOver = async () => {
24 | this.setState({
25 | show: true,
26 | })
27 | wokooAppZhihu.className = 'wokoo-app-unfold'
28 | this.getQueryName()
29 | this.getList()
30 | }
31 | handleMouseLeave = () => {
32 | this.setState({
33 | show: false,
34 | })
35 | wokooAppZhihu.className = 'wokoo-app-fold'
36 | }
37 | handleInfiniteOnLoad = () => {
38 | this.getList()
39 | }
40 |
41 | getQueryName = () => {
42 | let pathname = location.pathname
43 | let detailRegExp = /^\/p\/\d+/
44 | let queryName = ''
45 | // 专栏详情页
46 | if (detailRegExp.test(pathname)) {
47 | let aTage = document.getElementsByClassName(
48 | 'ColumnPageHeader-TitleColumn'
49 | )
50 | let url = aTage[0].href
51 | queryName = url.slice(url.lastIndexOf('/'))
52 | } else {
53 | // 专栏列表页
54 | // http://zhuanlan.zhihu和http://zhihu/column两种情况都是专栏
55 | if (pathname.indexOf('/column') === 0) {
56 | pathname = pathname.slice('/column'.length)
57 | }
58 | queryName = pathname
59 | }
60 | this.queryName = queryName
61 | }
62 |
63 | getList = async () => {
64 | if (!this.state.hasMore) return
65 | if (this.queryName === '/') return
66 | let { offset } = this.state
67 | let { data } = await axios.get(
68 | `https://www.zhihu.com/api/v4/columns${this.queryName}/items?limit=20&offset=${offset}`
69 | )
70 | let list = data.data.map((i) => ({
71 | title: i.title,
72 | url: i.url,
73 | id: i.id,
74 | commentCount: i.comment_count,
75 | voteupCount: i.voteup_count,
76 | }))
77 | if (data.paging.is_end) {
78 | this.setState({ hasMore: false })
79 | }
80 | offset += limit
81 |
82 | this.setState({
83 | list: [...this.state.list, ...list],
84 | offset,
85 | })
86 | }
87 |
88 | render() {
89 | let { show, list, hasMore } = this.state
90 | return (
91 | <>
92 | {show ? (
93 |
94 | Loading...}
99 | height={document.documentElement.clientHeight - 53}
100 | endMessage={
101 |
102 | 到底了,没内容啦~
103 |
104 | }
105 | >
106 | {list.map((i) => (
107 | -
108 |
109 | {i.title}
110 |
111 |
112 |
113 |
124 |
125 | {i.voteupCount} 赞同
126 |
127 |
128 |
129 |
140 |
141 | {i.commentCount} 条评论
142 |
143 |
144 | ))}
145 |
146 |
147 | ) : (
148 |
154 | 专栏目录
155 |
156 | »
157 |
158 |
159 | )}
160 | >
161 | )
162 | }
163 | }
164 |
--------------------------------------------------------------------------------
/example/zhihu-helper/src/app.less:
--------------------------------------------------------------------------------
1 | .wokoo-app-fold {
2 | position: fixed;
3 | top: 50%;
4 | margin-top: -47px;
5 | }
6 |
7 | .wokoo-app-unfold {
8 | position: fixed;
9 | top: 52px;
10 | height: calc(100% - 52px);
11 | width: 250px;
12 | z-index: 99;
13 | background: #fff;
14 | font-size: 14px;
15 | overflow: auto;
16 | overscroll-behavior: contain;
17 | -ms-scroll-chaining: contain;
18 | box-shadow: 1px 0px 3px rgb(18 18 18 / 10%);
19 | }
20 | ::-webkit-scrollbar {
21 | display: none; /* Chrome Safari */
22 | }
23 | .list-ul {
24 | padding: 10px;
25 | }
26 | .list-li {
27 | padding: 10px 0;
28 | border-bottom: 1px solid #f6f6f6;
29 | }
30 | .list-a {
31 | display: block;
32 | margin-bottom: 5px;
33 | }
34 | .list-span {
35 | width: 50%;
36 | display: inline-block;
37 | text-align: right;
38 | color: #8590a6;
39 | }
40 | .list-li:hover {
41 | color: #0066ff;
42 | }
43 | .octotree-toggle {
44 | display: flex;
45 | align-items: center;
46 | justify-content: center;
47 | font-size: 14px;
48 | left: 0;
49 | box-sizing: border-box;
50 | --color-text-primary: #24292e;
51 | --color-bg-canvas: #ffffff;
52 | --color-border-primary: #e1e4e8;
53 | color: var(--color-text-primary);
54 | background-color: var(--color-bg-canvas);
55 | box-shadow: 0 2px 8px var(--color-border-primary);
56 | opacity: 1;
57 | height: 94px;
58 | line-height: 1;
59 | position: absolute;
60 | right: -30px;
61 | text-align: center;
62 | top: 33%;
63 | width: 36px;
64 | z-index: 1000000001;
65 | cursor: pointer;
66 | border-radius: 0px 4px 4px 0px;
67 | border-left: none;
68 | padding: 6px;
69 | transition: right 0.25s ease-in 0.2s, opacity 0.35s ease-in 0.2s;
70 | }
71 | .octotree-toggle-icon {
72 | margin-left: 4px;
73 | }
74 | .svg-icon {
75 | display: inline-flex;
76 | align-self: center;
77 | position: relative;
78 | height: 1em;
79 | width: 1em;
80 | color: #0066ff;
81 | opacity: 0.3;
82 | margin-right: 5px;
83 | }
84 |
85 | .svg-icon svg {
86 | height: 1em;
87 | width: 1em;
88 | bottom: -0.125em;
89 | position: absolute;
90 | }
91 |
--------------------------------------------------------------------------------
/example/zhihu-helper/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import ReactDOM from 'react-dom'
3 | import App from './app'
4 |
5 | const wokooApp = document.createElement('div')
6 | wokooApp.id = 'wokooAppZhihu'
7 | wokooApp.className = 'wokoo-app-fold'
8 |
9 | document.body.appendChild(wokooApp)
10 | ReactDOM.render(
11 | ,
14 | wokooApp
15 | )
16 |
--------------------------------------------------------------------------------
/example/zhihu-helper/src/step1.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import './app.less'
3 |
4 | export default class extends React.Component {
5 | constructor(props) {
6 | super(props)
7 | this.state = {
8 | show: false,
9 | }
10 | }
11 | handleShow = () => {
12 | this.setState({
13 | show: !this.state.show,
14 | })
15 | }
16 | handleMouseOver = async () => {
17 | this.setState({
18 | show: true,
19 | })
20 | wokooAppZhihu.className = 'wokoo-app-unfold'
21 | }
22 | handleMouseLeave = () => {
23 | this.setState({
24 | show: false,
25 | })
26 | wokooAppZhihu.className = 'wokoo-app-fold'
27 | }
28 |
29 | render() {
30 | let { show } = this.state
31 | return (
32 | <>
33 | {show ? (
34 |
41 | ) : (
42 |
47 | 专栏目录
48 |
49 | »
50 |
51 |
52 | )}
53 | >
54 | )
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/example/zhihu-helper/src/step2.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import axios from 'axios'
3 | import './app.less'
4 |
5 | const limit = 20
6 | export default class extends React.Component {
7 | constructor(props) {
8 | super(props)
9 | this.state = {
10 | show: false,
11 | list: [],
12 | offset: 0,
13 | hasMore: true,
14 | }
15 | this.queryName = null
16 | }
17 | handleShow = () => {
18 | this.setState({
19 | show: !this.state.show,
20 | })
21 | }
22 | handleMouseOver = async () => {
23 | this.setState({
24 | show: true,
25 | })
26 | wokooAppZhihu.className = 'wokoo-app-unfold'
27 | this.getQueryName()
28 | this.getList()
29 | }
30 | handleMouseLeave = () => {
31 | this.setState({
32 | show: false,
33 | })
34 | wokooAppZhihu.className = 'wokoo-app'
35 | }
36 |
37 | getQueryName = () => {
38 | let pathname = location.pathname
39 | let detailRegExp = /^\/p\/\d+/
40 | let queryName = ''
41 | // 专栏详情页
42 | if (detailRegExp.test(pathname)) {
43 | let aTage = document.getElementsByClassName(
44 | 'ColumnPageHeader-TitleColumn'
45 | )
46 | let url = aTage[0].href
47 | queryName = url.slice(url.lastIndexOf('/'))
48 | } else {
49 | // 专栏列表页
50 | // http://zhuanlan.zhihu和http://zhihu/column两种情况都是专栏
51 | if (pathname.indexOf('/column') === 0) {
52 | pathname = pathname.slice('/column'.length)
53 | }
54 | queryName = pathname
55 | }
56 | this.queryName = queryName
57 | }
58 |
59 | getList = async () => {
60 | if (!this.state.hasMore) return
61 | let { offset } = this.state
62 | let { data } = await axios.get(
63 | `https://www.zhihu.com/api/v4/columns${this.queryName}/items?limit=20&offset=${offset}`
64 | )
65 | let list = data.data.map((i) => ({
66 | title: i.title,
67 | url: i.url,
68 | id: i.id,
69 | commentCount: i.comment_count,
70 | voteupCount: i.voteup_count,
71 | }))
72 | if (data.paging.is_end) {
73 | this.setState({ hasMore: false })
74 | }
75 | offset += limit
76 |
77 | this.setState({
78 | list: [...this.state.list, ...list],
79 | offset,
80 | })
81 | }
82 |
83 | render() {
84 | let { show, list, hasMore } = this.state
85 | return (
86 | <>
87 | {show ? (
88 |
89 | {list.map((i) => (
90 | -
91 |
92 | {i.title}
93 |
94 | {i.voteupCount} 赞同
95 | {i.commentCount} 条评论
96 |
97 | ))}
98 |
99 | ) : (
100 |
106 | 专栏目录
107 |
108 | »
109 |
110 |
111 | )}
112 | >
113 | )
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/example/zhihu-helper/tampermonkey.js:
--------------------------------------------------------------------------------
1 | // ==UserScript==
2 | // @name zhihu-helper
3 | // @namespace http://tampermonkey.net/
4 | // @version 0.0.1
5 | // @description 知乎目录
6 | // @author kinyaying
7 | // @match https://zhuanlan.zhihu.com/*
8 | // @match https://www.zhihu.com/column/*
9 | // @require https://unpkg.com/react@17/umd/react.production.min.js
10 | // @require https://unpkg.com/react-dom@17/umd/react-dom.production.min.js
11 |
12 | // ==/UserScript==
13 |
14 | ;(function () {
15 | 'use strict'
16 | if (location.href === 'http://localhost:8080/') return
17 | var script = document.createElement('script')
18 | script.src = 'http://localhost:8080/app.bundle.js'
19 | document.body.appendChild(script)
20 | })()
21 |
--------------------------------------------------------------------------------
/example/zhihu-helper/webpack.config.base.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | entry: {
3 | app: '/src/index.js',
4 | vendor: [
5 | // 将react和react-dom这些单独打包出来,减小打包文件体积
6 | 'react',
7 | 'react-dom',
8 | ],
9 | },
10 | module: {
11 | rules: [
12 | {
13 | test: /\.(js|jsx)$/, //匹配js文件
14 | use: {
15 | loader: 'babel-loader',
16 | options: {
17 | presets: ['@babel/preset-react', '@babel/preset-env'],
18 | plugins: [
19 | ['@babel/plugin-proposal-decorators', { legacy: true }],
20 | ['@babel/plugin-proposal-class-properties', { loose: true }],
21 | ],
22 | },
23 | },
24 | },
25 | ],
26 | },
27 | }
28 |
--------------------------------------------------------------------------------
/example/zhihu-helper/webpack.config.js:
--------------------------------------------------------------------------------
1 | const HtmlWebpackPlugin = require('html-webpack-plugin')
2 | const { merge } = require('webpack-merge')
3 | const base = require('./webpack.config.base')
4 |
5 | module.exports = merge(base, {
6 | mode: process.env.NODE_ENV || 'production',
7 | devtool: 'source-map',
8 | output: {
9 | filename: '[name].bundle.js',
10 | path: __dirname + '/dist',
11 | },
12 | module: {
13 | rules: [
14 | {
15 | test: /\.(less|css)$/,
16 | use: ['style-loader', 'css-loader', 'less-loader'],
17 | },
18 | {
19 | test: /\.(woff|woff2|eot|ttf|otf|png|svg|jpg|gif)$/,
20 | use: {
21 | loader: 'url-loader',
22 | options: {
23 | limit: 20480,
24 | },
25 | },
26 | },
27 | ],
28 | },
29 | plugins: [
30 | new HtmlWebpackPlugin({
31 | template: './public/index.html',
32 | }),
33 | ],
34 | })
35 |
--------------------------------------------------------------------------------
/lerna-debug.log:
--------------------------------------------------------------------------------
1 | 48 error Error: Command failed: git tag v0.1.7 -m v0.1.7
2 | 48 error fatal: tag 'v0.1.7' already exists
3 | 48 error
4 | 48 error at makeError (/Users/kin/MyCode/wokoo/node_modules/execa/index.js:174:9)
5 | 48 error at /Users/kin/MyCode/wokoo/node_modules/execa/index.js:278:16
6 | 48 error at processTicksAndRejections (internal/process/task_queues.js:97:5)
7 |
--------------------------------------------------------------------------------
/lerna.json:
--------------------------------------------------------------------------------
1 | {
2 | "packages": [
3 | "packages/*"
4 | ],
5 | "version": "0.3.3"
6 | }
7 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "wokoo-cli",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "private": true,
7 | "workspaces": [
8 | "packages/*"
9 | ],
10 | "scripts": {
11 | "start": "node packages/wokoo-scripts/index.js",
12 | "test": "node test.js"
13 | },
14 | "keywords": [],
15 | "author": "kinyaying",
16 | "license": "MIT",
17 | "devDependencies": {
18 | "lerna": "^3.22.1"
19 | },
20 | "dependencies": {
21 | "chalk": "^4.1.0",
22 | "cross-spawn": "^7.0.3",
23 | "fs-extra": "^9.0.1"
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/packages/wokoo-scripts/README.md:
--------------------------------------------------------------------------------
1 | # wokoo-scripts
2 |
3 | 使用 nodejs 编写的脚本工具,用于初始化一个基于 [wokoo-template](https://www.npmjs.com/package/wokoo-template) 模板的,有基础配置的油猴项目
4 |
5 | ## 功能
6 |
7 | - 分析用户在控制台输入的命令
8 | - 和用户交互,拉取 wokoo-template,生成对应的初始项目
9 |
10 | ## 使用
11 |
12 | 1. 安装
13 |
14 | ```
15 | npm i wokoo -g
16 | ```
17 |
18 | 2. 创建项目
19 |
20 | ```
21 | wokoo my-plugin
22 | ```
23 |
24 | 3. 命令行中会弹出询问:
25 | ? which template do you prefer?
26 | [ ] react
27 | [ ] vue
28 | 4. 选择对应模板,生成初始化项目
29 |
30 | ## 使用到的库
31 |
32 | - [chalk](https://www.npmjs.com/package/chalk) 丰富控制台显示的字颜色
33 | - [cross-spawn](https://www.npmjs.com/package/cross-spawn) 开启子线程
34 | - [commander](https://www.npmjs.com/package/commander) 提供命令行交互
35 | - [fs-extra](https://www.npmjs.com/package/fs-extra) 操作文件
36 | - [inquirer](https://www.npmjs.com/package/inquirer) 命令行弹出选项
37 | - [metalsmith](https://www.npmjs.com/package/metalsmith) 遍历文件夹
38 | - [consolidate](https://www.npmjs.com/package/consolidate) 渲染 ejs 模板
39 |
40 | ## 目录结构
41 |
42 | ```
43 | .
44 | ├── README.md
45 | ├── bin
46 | │ └── www 入口文件
47 | ├── index.js 主程序
48 | ├── modifyTemplate.js 将temp目录下的ejs语法,替换成js变量
49 | ├── package-lock.json
50 | └── package.json
51 | ```
52 |
53 | ## 了解更多
54 |
55 | 如果想了解更多内容,请访问下面的网址:
56 | [油猴脚手架 wokoo 使用说明](https://juejin.cn/post/6922815205575491597)
57 | [油猴脚手架 wokoo git 仓库](https://github.com/kinyaying/wokoo)
58 |
--------------------------------------------------------------------------------
/packages/wokoo-scripts/bin/www:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env node
2 |
3 | require('../index.js');
--------------------------------------------------------------------------------
/packages/wokoo-scripts/index.js:
--------------------------------------------------------------------------------
1 | const chalk = require('chalk')
2 | const spawn = require('cross-spawn')
3 | const { Command } = require('commander')
4 | const fs = require('fs-extra')
5 | const path = require('path')
6 | const inquirer = require('inquirer')
7 | const packageJson = require('./package.json')
8 | const modifyTemplate = require('./modifyTemplate') // 修改替换ejs模板内字段
9 | let program = new Command()
10 | init()
11 | // 程序入口,读取命令行脚本,获得项目名称
12 | async function init() {
13 | let projectName, target
14 | program
15 | .version(packageJson.version)
16 | .arguments('') // 项目目录名 参数格式:<必选> [可选]
17 | .usage(`${chalk.green(``)}`)
18 | .option('-t, --target [value]', 'chose template')
19 | .action((...argvs) => {
20 | const [name] = argvs
21 | projectName = name
22 | target = argvs[1].target
23 | })
24 | .parse(process.argv) // [node路径,脚本路径,参数]
25 | await createApp(projectName, target)
26 | }
27 | /**
28 | * 根据appName生成项目目录
29 | * @param {*} appName
30 | */
31 | async function createApp(appName, target) {
32 | let root = path.resolve(appName) // 要生成的项目的绝对路径
33 | fs.ensureDirSync(appName) // 没有则创建文件夹
34 | console.log(`create a new app in ${chalk.green(root)}`)
35 | // 初始化package.json
36 | const packageJson = {
37 | name: appName,
38 | version: '0.0.1',
39 | private: true,
40 | scripts: {
41 | start: 'cross-env NODE_ENV=development webpack serve',
42 | build: 'webpack',
43 | },
44 | }
45 | // 写入package.json
46 | fs.writeFileSync(
47 | path.join(root, 'package.json'),
48 | JSON.stringify(packageJson, null, 2)
49 | )
50 | // 改变工作目录,进入项目目录
51 | process.chdir(root)
52 | // 复制项目模板,安装项目依赖等
53 | await run(root, appName, target)
54 | }
55 | /**
56 | 1、安装wokoo-template
57 | 2、复制模板文件到临时文件夹temp,
58 | 3、调用modifyTemplate替换其中的ejs模板
59 | 4、删除临时文件夹temp
60 | 5、卸载wokoo-template
61 | * @param {*} root 项目路径
62 | * @param {*} appName 项目名
63 | */
64 | async function run(root, appName, target) {
65 | const templateName = 'wokoo-template' // 对应的wokoo模板
66 | const allDependencies = [templateName]
67 | // 安装wokoo-template包
68 | console.log('Installing packages. This might take a couple of minutes')
69 | console.log(`Installing ${chalk.cyan(templateName)} ...`)
70 | try {
71 | await doAction(root, allDependencies)
72 | } catch (e) {
73 | console.log(`Installing ${chalk.red(templateName)} failed ...`, e)
74 | }
75 | console.log(`Installing ${chalk.cyan(templateName)} succeed!`)
76 |
77 | // 选择模板
78 | const repos = ['vue', 'react']
79 | let targetTemplate
80 | if(target) {
81 | targetTemplate = target
82 | console.log('This is a test project:' + target)
83 | } else {
84 | const data = await inquirer.prompt({
85 | name: 'targetTemplate',
86 | type: 'list',
87 | message: 'which template do you prefer?',
88 | choices: repos, // 选择模式
89 | })
90 | targetTemplate = data.targetTemplate
91 | }
92 |
93 | const templatePath = path.dirname(
94 | require.resolve(`${templateName}/package.json`, { paths: [root] })
95 | )
96 |
97 | // 复制文件到项目目录
98 | const scriptsConfigDir = path.join(templatePath, 'webpack.config.js')
99 | const gitIgnoreDir = path.join(templatePath, '.npmignore')
100 | const publicDir = path.join(templatePath, 'public')
101 | const tempDir = path.join(root, 'temp') // 临时模板路径
102 | const templateDir = path.join(templatePath, `${targetTemplate}-template`)
103 | // 从wokoo-template中拷贝模板到项目目录
104 | if (fs.existsSync(templatePath)) {
105 | // 将templateDir内模板拷贝到temp文件,并修改模板文件中的ejs配置项
106 | await modifyTemplate(templateDir, 'temp', {
107 | projectName: appName,
108 | basicProject: targetTemplate,
109 | })
110 |
111 | fs.copySync(tempDir, root) // 源 目标
112 | fs.copySync(publicDir, root + '/public')
113 | fs.copyFileSync(scriptsConfigDir, root + '/webpack.config.js')
114 | fs.copyFileSync(gitIgnoreDir, root + '/.gitignore')
115 | deleteFolder(tempDir)
116 | } else {
117 | console.error(
118 | `Could not locate supplied template: ${chalk.green(templatePath)}`
119 | )
120 | return
121 | }
122 | // 合并template.json和package.json
123 | let tempPkg = fs.readFileSync(root + '/template.json').toString()
124 | let pkg = fs.readFileSync(root + '/package.json').toString()
125 | const tempPkgJson = JSON.parse(tempPkg)
126 | const pkgJson = JSON.parse(pkg)
127 |
128 | pkgJson.dependencies = {
129 | ...pkgJson.dependencies,
130 | ...tempPkgJson.package.dependencies,
131 | }
132 | pkgJson.devDependencies = {
133 | ...tempPkgJson.package.devDependencies,
134 | }
135 | // 编写package.json
136 | fs.writeFileSync(
137 | path.join(root, 'package.json'),
138 | JSON.stringify(pkgJson, null, 2)
139 | )
140 | fs.unlinkSync(path.join(root, 'template.json')) // 删除template.json文件
141 |
142 | // 再次根据dependenciesToInstall执行npm install
143 | const dependenciesToInstall = Object.entries({
144 | ...pkgJson.dependencies,
145 | ...pkgJson.devDependencies,
146 | })
147 | let newDependencies = []
148 | if (dependenciesToInstall.length) {
149 | newDependencies = newDependencies.concat(
150 | dependenciesToInstall.map(([dependency, version]) => {
151 | return `${dependency}@${version}`
152 | })
153 | )
154 | }
155 | await doAction(root, newDependencies)
156 | console.log(`${chalk.cyan('Installing succeed!')}`)
157 |
158 | // 卸载wokoo-template
159 | await doAction(root, 'wokoo-template', 'uninstall')
160 |
161 | console.log(`🎉 Successfully created project ${appName}.`)
162 | console.log('👉 Get started with the following commands:')
163 | console.log(`${chalk.cyan(`cd ${appName}`)}`)
164 | console.log(`${chalk.cyan('$ npm start')}`)
165 |
166 | process.exit(0)
167 | }
168 |
169 | /**
170 | * 使用npm安装或卸载项目依赖
171 | * @param {*} root 项目路径
172 | * @param {*} allDependencies 项目依赖
173 | * @param {*} action npm install 或 npm uninstall
174 | */
175 | async function doAction(root, allDependencies, action = 'install') {
176 | typeof allDependencies === 'string'
177 | ? (allDependencies = [allDependencies])
178 | : null
179 | return new Promise((resolve) => {
180 | const command = 'npm'
181 | const args = [
182 | action,
183 | '--save',
184 | '--save-exact',
185 | '--loglevel',
186 | 'error',
187 | ...allDependencies,
188 | '--prefix',
189 | root,
190 | ]
191 | const child = spawn(command, args, { stdio: 'inherit' })
192 | child.on('close', resolve) // 安装成功后触发resolve
193 | })
194 | }
195 |
196 | /**
197 | * 删除文件、文件夹
198 | * @param {*} path 要删除资源的路径
199 | */
200 | function deleteFolder(path) {
201 | let files = []
202 | if (fs.existsSync(path)) {
203 | if (!fs.statSync(path).isDirectory()) {
204 | // path是文件,直接删除
205 | fs.unlinkSync(path)
206 | } else {
207 | // 删除文件夹
208 | files = fs.readdirSync(path)
209 | files.forEach(function (file) {
210 | let curPath = path + '/' + file
211 | deleteFolder(curPath)
212 | })
213 | fs.rmdirSync(path)
214 | }
215 | }
216 | }
217 |
--------------------------------------------------------------------------------
/packages/wokoo-scripts/modifyTemplate.js:
--------------------------------------------------------------------------------
1 | const MetalSmith = require('metalsmith') // 遍历文件夹
2 | let { render } = require('consolidate').ejs
3 | const { promisify } = require('util')
4 | const path = require('path')
5 | render = promisify(render) // 包装渲染方法
6 |
7 | /**
8 | * 遍历template文件夹,将内部的.js .json .txt .md文件中ejs模板替换成注入的变量
9 | * 例如 wokoo-template/vue-template/tampermokey.js 文件中的 <%=projectName%> 会被替换成config中的projectName
10 | * @param {*} fromPath 源路径
11 | * @param {*} toPath 目标路径
12 | * @param {object} config 配置,eg.
13 | * {
14 | projectName: appName,
15 | basicProject: targetTemplate,
16 | }
17 | */
18 | async function handleTemplate(fromPath, toPath, config) {
19 | await new Promise((resovle, reject) => {
20 | MetalSmith(__dirname)
21 | .source(fromPath) // 遍历下载的目录
22 | .destination(path.join(path.resolve(), toPath)) // 输出渲染后的结果
23 | .use(async (files, metal, done) => {
24 | // result 替换模板内数据
25 | let result = {
26 | license: 'MIT',
27 | version: '0.0.1',
28 | ...config,
29 | randomNumber: new Date().getTime().toString().slice(8),
30 | }
31 | const data = metal.metadata()
32 | Object.assign(data, result) // 将询问的结果放到metadata中保证在下一个中间件中可以获取到
33 | done()
34 | })
35 | .use((files, metal, done) => {
36 | Reflect.ownKeys(files).forEach(async (file) => {
37 | let content = files[file].contents.toString() // 获取文件中的内容
38 | if (
39 | file.includes('.js') ||
40 | file.includes('.json') ||
41 | file.includes('.txt') ||
42 | file.includes('.md')
43 | ) {
44 | // 如果是md或者txt才有可能是模板
45 | if (content.includes('<%')) {
46 | // 文件中用<% 我才需要编译
47 | content = await render(content, metal.metadata()) // 用数据渲染模板
48 | files[file].contents = Buffer.from(content) // 渲染好的结果替换即可
49 | }
50 | }
51 | })
52 | done()
53 | })
54 | .build((err) => {
55 | // 执行中间件
56 | if (!err) {
57 | resovle()
58 | } else {
59 | reject(err)
60 | }
61 | })
62 | })
63 | }
64 |
65 | module.exports = handleTemplate
66 |
--------------------------------------------------------------------------------
/packages/wokoo-scripts/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "wokoo",
3 | "version": "0.3.3",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "absolute": {
8 | "version": "0.0.1",
9 | "resolved": "https://registry.npmjs.org/absolute/-/absolute-0.0.1.tgz",
10 | "integrity": "sha1-wigi+H4ck59XmIdQTZwQnEFzgp0="
11 | },
12 | "ansi-escapes": {
13 | "version": "4.3.1",
14 | "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz",
15 | "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==",
16 | "requires": {
17 | "type-fest": "^0.11.0"
18 | }
19 | },
20 | "ansi-red": {
21 | "version": "0.1.1",
22 | "resolved": "https://registry.npmjs.org/ansi-red/-/ansi-red-0.1.1.tgz",
23 | "integrity": "sha1-jGOPnRCAgAo1PJwoyKgcpHBdlGw=",
24 | "requires": {
25 | "ansi-wrap": "0.1.0"
26 | }
27 | },
28 | "ansi-regex": {
29 | "version": "5.0.0",
30 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
31 | "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg=="
32 | },
33 | "ansi-styles": {
34 | "version": "4.3.0",
35 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
36 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
37 | "requires": {
38 | "color-convert": "^2.0.1"
39 | }
40 | },
41 | "ansi-wrap": {
42 | "version": "0.1.0",
43 | "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz",
44 | "integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768="
45 | },
46 | "argparse": {
47 | "version": "1.0.10",
48 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
49 | "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
50 | "requires": {
51 | "sprintf-js": "~1.0.2"
52 | }
53 | },
54 | "async": {
55 | "version": "0.9.2",
56 | "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz",
57 | "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0="
58 | },
59 | "at-least-node": {
60 | "version": "1.0.0",
61 | "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz",
62 | "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg=="
63 | },
64 | "balanced-match": {
65 | "version": "1.0.0",
66 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
67 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
68 | },
69 | "bluebird": {
70 | "version": "3.7.2",
71 | "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
72 | "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg=="
73 | },
74 | "brace-expansion": {
75 | "version": "1.1.11",
76 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
77 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
78 | "requires": {
79 | "balanced-match": "^1.0.0",
80 | "concat-map": "0.0.1"
81 | }
82 | },
83 | "chalk": {
84 | "version": "4.1.0",
85 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
86 | "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
87 | "requires": {
88 | "ansi-styles": "^4.1.0",
89 | "supports-color": "^7.1.0"
90 | }
91 | },
92 | "chardet": {
93 | "version": "0.7.0",
94 | "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz",
95 | "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA=="
96 | },
97 | "cli-cursor": {
98 | "version": "3.1.0",
99 | "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
100 | "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
101 | "requires": {
102 | "restore-cursor": "^3.1.0"
103 | }
104 | },
105 | "cli-width": {
106 | "version": "3.0.0",
107 | "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz",
108 | "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw=="
109 | },
110 | "clone": {
111 | "version": "1.0.4",
112 | "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
113 | "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4="
114 | },
115 | "co": {
116 | "version": "3.1.0",
117 | "resolved": "https://registry.npmjs.org/co/-/co-3.1.0.tgz",
118 | "integrity": "sha1-TqVOpaCJOBUxheFSEMaNkJK8G3g="
119 | },
120 | "co-from-stream": {
121 | "version": "0.0.0",
122 | "resolved": "https://registry.npmjs.org/co-from-stream/-/co-from-stream-0.0.0.tgz",
123 | "integrity": "sha1-GlzYztdyY5RglPo58kmaYyl7yvk=",
124 | "requires": {
125 | "co-read": "0.0.1"
126 | }
127 | },
128 | "co-fs-extra": {
129 | "version": "1.2.1",
130 | "resolved": "https://registry.npmjs.org/co-fs-extra/-/co-fs-extra-1.2.1.tgz",
131 | "integrity": "sha1-O2rXfPJhRTD2d7HPYmZPW6dWtyI=",
132 | "requires": {
133 | "co-from-stream": "~0.0.0",
134 | "fs-extra": "~0.26.5",
135 | "thunkify-wrap": "~1.0.4"
136 | },
137 | "dependencies": {
138 | "fs-extra": {
139 | "version": "0.26.7",
140 | "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.26.7.tgz",
141 | "integrity": "sha1-muH92UiXeY7at20JGM9C0MMYT6k=",
142 | "requires": {
143 | "graceful-fs": "^4.1.2",
144 | "jsonfile": "^2.1.0",
145 | "klaw": "^1.0.0",
146 | "path-is-absolute": "^1.0.0",
147 | "rimraf": "^2.2.8"
148 | }
149 | },
150 | "jsonfile": {
151 | "version": "2.4.0",
152 | "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz",
153 | "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=",
154 | "requires": {
155 | "graceful-fs": "^4.1.6"
156 | }
157 | }
158 | }
159 | },
160 | "co-read": {
161 | "version": "0.0.1",
162 | "resolved": "https://registry.npmjs.org/co-read/-/co-read-0.0.1.tgz",
163 | "integrity": "sha1-+Bs+uKhmdf7FHj2IOn9WToc8k4k="
164 | },
165 | "coffee-script": {
166 | "version": "1.12.7",
167 | "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.12.7.tgz",
168 | "integrity": "sha512-fLeEhqwymYat/MpTPUjSKHVYYl0ec2mOyALEMLmzr5i1isuG+6jfI2j2d5oBO3VIzgUXgBVIcOT9uH1TFxBckw=="
169 | },
170 | "color-convert": {
171 | "version": "2.0.1",
172 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
173 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
174 | "requires": {
175 | "color-name": "~1.1.4"
176 | }
177 | },
178 | "color-name": {
179 | "version": "1.1.4",
180 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
181 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
182 | },
183 | "commander": {
184 | "version": "7.0.0",
185 | "resolved": "https://registry.npmjs.org/commander/-/commander-7.0.0.tgz",
186 | "integrity": "sha512-ovx/7NkTrnPuIV8sqk/GjUIIM1+iUQeqA3ye2VNpq9sVoiZsooObWlQy+OPWGI17GDaEoybuAGJm6U8yC077BA=="
187 | },
188 | "concat-map": {
189 | "version": "0.0.1",
190 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
191 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
192 | },
193 | "consolidate": {
194 | "version": "0.16.0",
195 | "resolved": "https://registry.npmjs.org/consolidate/-/consolidate-0.16.0.tgz",
196 | "integrity": "sha512-Nhl1wzCslqXYTJVDyJCu3ODohy9OfBMB5uD2BiBTzd7w+QY0lBzafkR8y8755yMYHAaMD4NuzbAw03/xzfw+eQ==",
197 | "requires": {
198 | "bluebird": "^3.7.2"
199 | }
200 | },
201 | "cross-spawn": {
202 | "version": "7.0.3",
203 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
204 | "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
205 | "requires": {
206 | "path-key": "^3.1.0",
207 | "shebang-command": "^2.0.0",
208 | "which": "^2.0.1"
209 | }
210 | },
211 | "ejs": {
212 | "version": "3.1.5",
213 | "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.5.tgz",
214 | "integrity": "sha512-dldq3ZfFtgVTJMLjOe+/3sROTzALlL9E34V4/sDtUd/KlBSS0s6U1/+WPE1B4sj9CXHJpL1M6rhNJnc9Wbal9w==",
215 | "requires": {
216 | "jake": "^10.6.1"
217 | }
218 | },
219 | "emoji-regex": {
220 | "version": "8.0.0",
221 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
222 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
223 | },
224 | "enable": {
225 | "version": "1.3.2",
226 | "resolved": "https://registry.npmjs.org/enable/-/enable-1.3.2.tgz",
227 | "integrity": "sha1-nrpoN9FtCYK1n4fYib91REPVKTE="
228 | },
229 | "escape-string-regexp": {
230 | "version": "1.0.5",
231 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
232 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
233 | },
234 | "esprima": {
235 | "version": "4.0.1",
236 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
237 | "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="
238 | },
239 | "extend-shallow": {
240 | "version": "2.0.1",
241 | "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
242 | "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
243 | "requires": {
244 | "is-extendable": "^0.1.0"
245 | }
246 | },
247 | "external-editor": {
248 | "version": "3.1.0",
249 | "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz",
250 | "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==",
251 | "requires": {
252 | "chardet": "^0.7.0",
253 | "iconv-lite": "^0.4.24",
254 | "tmp": "^0.0.33"
255 | }
256 | },
257 | "figures": {
258 | "version": "3.2.0",
259 | "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz",
260 | "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==",
261 | "requires": {
262 | "escape-string-regexp": "^1.0.5"
263 | }
264 | },
265 | "filelist": {
266 | "version": "1.0.1",
267 | "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.1.tgz",
268 | "integrity": "sha512-8zSK6Nu0DQIC08mUC46sWGXi+q3GGpKydAG36k+JDba6VRpkevvOWUW5a/PhShij4+vHT9M+ghgG7eM+a9JDUQ==",
269 | "requires": {
270 | "minimatch": "^3.0.4"
271 | }
272 | },
273 | "fs-extra": {
274 | "version": "9.1.0",
275 | "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
276 | "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
277 | "requires": {
278 | "at-least-node": "^1.0.0",
279 | "graceful-fs": "^4.2.0",
280 | "jsonfile": "^6.0.1",
281 | "universalify": "^2.0.0"
282 | }
283 | },
284 | "fs.realpath": {
285 | "version": "1.0.0",
286 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
287 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
288 | },
289 | "glob": {
290 | "version": "7.1.6",
291 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
292 | "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
293 | "requires": {
294 | "fs.realpath": "^1.0.0",
295 | "inflight": "^1.0.4",
296 | "inherits": "2",
297 | "minimatch": "^3.0.4",
298 | "once": "^1.3.0",
299 | "path-is-absolute": "^1.0.0"
300 | }
301 | },
302 | "graceful-fs": {
303 | "version": "4.2.4",
304 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
305 | "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw=="
306 | },
307 | "gray-matter": {
308 | "version": "2.1.1",
309 | "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-2.1.1.tgz",
310 | "integrity": "sha1-MELZrewqHe1qdwep7SOA+KF6Qw4=",
311 | "requires": {
312 | "ansi-red": "^0.1.1",
313 | "coffee-script": "^1.12.4",
314 | "extend-shallow": "^2.0.1",
315 | "js-yaml": "^3.8.1",
316 | "toml": "^2.3.2"
317 | }
318 | },
319 | "has-ansi": {
320 | "version": "2.0.0",
321 | "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
322 | "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
323 | "requires": {
324 | "ansi-regex": "^2.0.0"
325 | },
326 | "dependencies": {
327 | "ansi-regex": {
328 | "version": "2.1.1",
329 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
330 | "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
331 | }
332 | }
333 | },
334 | "has-flag": {
335 | "version": "4.0.0",
336 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
337 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
338 | },
339 | "has-generators": {
340 | "version": "1.0.1",
341 | "resolved": "https://registry.npmjs.org/has-generators/-/has-generators-1.0.1.tgz",
342 | "integrity": "sha1-pqLlVIYBGUBILhPiyTeRxEms9Ek="
343 | },
344 | "iconv-lite": {
345 | "version": "0.4.24",
346 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
347 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
348 | "requires": {
349 | "safer-buffer": ">= 2.1.2 < 3"
350 | }
351 | },
352 | "inflight": {
353 | "version": "1.0.6",
354 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
355 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
356 | "requires": {
357 | "once": "^1.3.0",
358 | "wrappy": "1"
359 | }
360 | },
361 | "inherits": {
362 | "version": "2.0.4",
363 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
364 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
365 | },
366 | "inquirer": {
367 | "version": "7.3.3",
368 | "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz",
369 | "integrity": "sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==",
370 | "requires": {
371 | "ansi-escapes": "^4.2.1",
372 | "chalk": "^4.1.0",
373 | "cli-cursor": "^3.1.0",
374 | "cli-width": "^3.0.0",
375 | "external-editor": "^3.0.3",
376 | "figures": "^3.0.0",
377 | "lodash": "^4.17.19",
378 | "mute-stream": "0.0.8",
379 | "run-async": "^2.4.0",
380 | "rxjs": "^6.6.0",
381 | "string-width": "^4.1.0",
382 | "strip-ansi": "^6.0.0",
383 | "through": "^2.3.6"
384 | }
385 | },
386 | "is": {
387 | "version": "3.3.0",
388 | "resolved": "https://registry.npmjs.org/is/-/is-3.3.0.tgz",
389 | "integrity": "sha512-nW24QBoPcFGGHJGUwnfpI7Yc5CdqWNdsyHQszVE/z2pKHXzh7FZ5GWhJqSyaQ9wMkQnsTx+kAI8bHlCX4tKdbg=="
390 | },
391 | "is-extendable": {
392 | "version": "0.1.1",
393 | "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
394 | "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik="
395 | },
396 | "is-fullwidth-code-point": {
397 | "version": "3.0.0",
398 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
399 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
400 | },
401 | "is-utf8": {
402 | "version": "0.2.1",
403 | "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
404 | "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI="
405 | },
406 | "isexe": {
407 | "version": "2.0.0",
408 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
409 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA="
410 | },
411 | "jake": {
412 | "version": "10.8.2",
413 | "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.2.tgz",
414 | "integrity": "sha512-eLpKyrfG3mzvGE2Du8VoPbeSkRry093+tyNjdYaBbJS9v17knImYGNXQCUV0gLxQtF82m3E8iRb/wdSQZLoq7A==",
415 | "requires": {
416 | "async": "0.9.x",
417 | "chalk": "^2.4.2",
418 | "filelist": "^1.0.1",
419 | "minimatch": "^3.0.4"
420 | },
421 | "dependencies": {
422 | "ansi-styles": {
423 | "version": "3.2.1",
424 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
425 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
426 | "requires": {
427 | "color-convert": "^1.9.0"
428 | }
429 | },
430 | "chalk": {
431 | "version": "2.4.2",
432 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
433 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
434 | "requires": {
435 | "ansi-styles": "^3.2.1",
436 | "escape-string-regexp": "^1.0.5",
437 | "supports-color": "^5.3.0"
438 | }
439 | },
440 | "color-convert": {
441 | "version": "1.9.3",
442 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
443 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
444 | "requires": {
445 | "color-name": "1.1.3"
446 | }
447 | },
448 | "color-name": {
449 | "version": "1.1.3",
450 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
451 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
452 | },
453 | "has-flag": {
454 | "version": "3.0.0",
455 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
456 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
457 | },
458 | "supports-color": {
459 | "version": "5.5.0",
460 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
461 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
462 | "requires": {
463 | "has-flag": "^3.0.0"
464 | }
465 | }
466 | }
467 | },
468 | "js-yaml": {
469 | "version": "3.14.1",
470 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
471 | "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
472 | "requires": {
473 | "argparse": "^1.0.7",
474 | "esprima": "^4.0.0"
475 | }
476 | },
477 | "jsonfile": {
478 | "version": "6.1.0",
479 | "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
480 | "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
481 | "requires": {
482 | "graceful-fs": "^4.1.6",
483 | "universalify": "^2.0.0"
484 | }
485 | },
486 | "klaw": {
487 | "version": "1.3.1",
488 | "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz",
489 | "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=",
490 | "requires": {
491 | "graceful-fs": "^4.1.9"
492 | }
493 | },
494 | "lodash": {
495 | "version": "4.17.20",
496 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
497 | "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA=="
498 | },
499 | "metalsmith": {
500 | "version": "2.3.0",
501 | "resolved": "https://registry.npmjs.org/metalsmith/-/metalsmith-2.3.0.tgz",
502 | "integrity": "sha1-gzr7taKmOF4tmuPZNeOeM+rqUjE=",
503 | "requires": {
504 | "absolute": "0.0.1",
505 | "chalk": "^1.1.3",
506 | "clone": "^1.0.2",
507 | "co-fs-extra": "^1.2.1",
508 | "commander": "^2.6.0",
509 | "gray-matter": "^2.0.0",
510 | "has-generators": "^1.0.1",
511 | "is": "^3.1.0",
512 | "is-utf8": "~0.2.0",
513 | "recursive-readdir": "^2.1.0",
514 | "rimraf": "^2.2.8",
515 | "stat-mode": "^0.2.0",
516 | "thunkify": "^2.1.2",
517 | "unyield": "0.0.1",
518 | "ware": "^1.2.0",
519 | "win-fork": "^1.1.1"
520 | },
521 | "dependencies": {
522 | "ansi-regex": {
523 | "version": "2.1.1",
524 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
525 | "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
526 | },
527 | "ansi-styles": {
528 | "version": "2.2.1",
529 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
530 | "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4="
531 | },
532 | "chalk": {
533 | "version": "1.1.3",
534 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
535 | "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
536 | "requires": {
537 | "ansi-styles": "^2.2.1",
538 | "escape-string-regexp": "^1.0.2",
539 | "has-ansi": "^2.0.0",
540 | "strip-ansi": "^3.0.0",
541 | "supports-color": "^2.0.0"
542 | }
543 | },
544 | "commander": {
545 | "version": "2.20.3",
546 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
547 | "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
548 | },
549 | "strip-ansi": {
550 | "version": "3.0.1",
551 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
552 | "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
553 | "requires": {
554 | "ansi-regex": "^2.0.0"
555 | }
556 | },
557 | "supports-color": {
558 | "version": "2.0.0",
559 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
560 | "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc="
561 | }
562 | }
563 | },
564 | "mimic-fn": {
565 | "version": "2.1.0",
566 | "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
567 | "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="
568 | },
569 | "minimatch": {
570 | "version": "3.0.4",
571 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
572 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
573 | "requires": {
574 | "brace-expansion": "^1.1.7"
575 | }
576 | },
577 | "mute-stream": {
578 | "version": "0.0.8",
579 | "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz",
580 | "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA=="
581 | },
582 | "once": {
583 | "version": "1.4.0",
584 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
585 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
586 | "requires": {
587 | "wrappy": "1"
588 | }
589 | },
590 | "onetime": {
591 | "version": "5.1.2",
592 | "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
593 | "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
594 | "requires": {
595 | "mimic-fn": "^2.1.0"
596 | }
597 | },
598 | "os-tmpdir": {
599 | "version": "1.0.2",
600 | "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
601 | "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ="
602 | },
603 | "path-is-absolute": {
604 | "version": "1.0.1",
605 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
606 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
607 | },
608 | "path-key": {
609 | "version": "3.1.1",
610 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
611 | "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="
612 | },
613 | "recursive-readdir": {
614 | "version": "2.2.2",
615 | "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.2.tgz",
616 | "integrity": "sha512-nRCcW9Sj7NuZwa2XvH9co8NPeXUBhZP7CRKJtU+cS6PW9FpCIFoI5ib0NT1ZrbNuPoRy0ylyCaUL8Gih4LSyFg==",
617 | "requires": {
618 | "minimatch": "3.0.4"
619 | }
620 | },
621 | "restore-cursor": {
622 | "version": "3.1.0",
623 | "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
624 | "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
625 | "requires": {
626 | "onetime": "^5.1.0",
627 | "signal-exit": "^3.0.2"
628 | }
629 | },
630 | "rimraf": {
631 | "version": "2.7.1",
632 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
633 | "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
634 | "requires": {
635 | "glob": "^7.1.3"
636 | }
637 | },
638 | "run-async": {
639 | "version": "2.4.1",
640 | "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz",
641 | "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ=="
642 | },
643 | "rxjs": {
644 | "version": "6.6.3",
645 | "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.3.tgz",
646 | "integrity": "sha512-trsQc+xYYXZ3urjOiJOuCOa5N3jAZ3eiSpQB5hIT8zGlL2QfnHLJ2r7GMkBGuIausdJN1OneaI6gQlsqNHHmZQ==",
647 | "requires": {
648 | "tslib": "^1.9.0"
649 | }
650 | },
651 | "safer-buffer": {
652 | "version": "2.1.2",
653 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
654 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
655 | },
656 | "shebang-command": {
657 | "version": "2.0.0",
658 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
659 | "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
660 | "requires": {
661 | "shebang-regex": "^3.0.0"
662 | }
663 | },
664 | "shebang-regex": {
665 | "version": "3.0.0",
666 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
667 | "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="
668 | },
669 | "signal-exit": {
670 | "version": "3.0.3",
671 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
672 | "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA=="
673 | },
674 | "sprintf-js": {
675 | "version": "1.0.3",
676 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
677 | "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
678 | },
679 | "stat-mode": {
680 | "version": "0.2.2",
681 | "resolved": "https://registry.npmjs.org/stat-mode/-/stat-mode-0.2.2.tgz",
682 | "integrity": "sha1-5sgLYjEj19gM8TLOU480YokHJQI="
683 | },
684 | "string-width": {
685 | "version": "4.2.0",
686 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
687 | "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
688 | "requires": {
689 | "emoji-regex": "^8.0.0",
690 | "is-fullwidth-code-point": "^3.0.0",
691 | "strip-ansi": "^6.0.0"
692 | }
693 | },
694 | "strip-ansi": {
695 | "version": "6.0.0",
696 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
697 | "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
698 | "requires": {
699 | "ansi-regex": "^5.0.0"
700 | }
701 | },
702 | "supports-color": {
703 | "version": "7.2.0",
704 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
705 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
706 | "requires": {
707 | "has-flag": "^4.0.0"
708 | }
709 | },
710 | "through": {
711 | "version": "2.3.8",
712 | "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
713 | "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU="
714 | },
715 | "thunkify": {
716 | "version": "2.1.2",
717 | "resolved": "https://registry.npmjs.org/thunkify/-/thunkify-2.1.2.tgz",
718 | "integrity": "sha1-+qDp0jDFGsyVyhOjYawFyn4EVT0="
719 | },
720 | "thunkify-wrap": {
721 | "version": "1.0.4",
722 | "resolved": "https://registry.npmjs.org/thunkify-wrap/-/thunkify-wrap-1.0.4.tgz",
723 | "integrity": "sha1-tSvlSN3+/aIOALWMYJZ2K0PdaIA=",
724 | "requires": {
725 | "enable": "1"
726 | }
727 | },
728 | "tmp": {
729 | "version": "0.0.33",
730 | "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
731 | "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
732 | "requires": {
733 | "os-tmpdir": "~1.0.2"
734 | }
735 | },
736 | "toml": {
737 | "version": "2.3.6",
738 | "resolved": "https://registry.npmjs.org/toml/-/toml-2.3.6.tgz",
739 | "integrity": "sha512-gVweAectJU3ebq//Ferr2JUY4WKSDe5N+z0FvjDncLGyHmIDoxgY/2Ie4qfEIDm4IS7OA6Rmdm7pdEEdMcV/xQ=="
740 | },
741 | "tslib": {
742 | "version": "1.14.1",
743 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
744 | "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
745 | },
746 | "type-fest": {
747 | "version": "0.11.0",
748 | "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz",
749 | "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ=="
750 | },
751 | "universalify": {
752 | "version": "2.0.0",
753 | "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
754 | "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ=="
755 | },
756 | "unyield": {
757 | "version": "0.0.1",
758 | "resolved": "https://registry.npmjs.org/unyield/-/unyield-0.0.1.tgz",
759 | "integrity": "sha1-FQ5l2kK/d0JEW5WKZOubhdHSsYA=",
760 | "requires": {
761 | "co": "~3.1.0"
762 | }
763 | },
764 | "ware": {
765 | "version": "1.3.0",
766 | "resolved": "https://registry.npmjs.org/ware/-/ware-1.3.0.tgz",
767 | "integrity": "sha1-0bFPOdLiy0q4xAmPdW/ksWTkc9Q=",
768 | "requires": {
769 | "wrap-fn": "^0.1.0"
770 | }
771 | },
772 | "which": {
773 | "version": "2.0.2",
774 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
775 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
776 | "requires": {
777 | "isexe": "^2.0.0"
778 | }
779 | },
780 | "win-fork": {
781 | "version": "1.1.1",
782 | "resolved": "https://registry.npmjs.org/win-fork/-/win-fork-1.1.1.tgz",
783 | "integrity": "sha1-j1jgZW/KAK3IyGoriePNLWotXl4="
784 | },
785 | "wrap-fn": {
786 | "version": "0.1.5",
787 | "resolved": "https://registry.npmjs.org/wrap-fn/-/wrap-fn-0.1.5.tgz",
788 | "integrity": "sha1-8htuQQFv9KfjFyDbxjoJAWvfmEU=",
789 | "requires": {
790 | "co": "3.1.0"
791 | }
792 | },
793 | "wrappy": {
794 | "version": "1.0.2",
795 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
796 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
797 | }
798 | }
799 | }
800 |
--------------------------------------------------------------------------------
/packages/wokoo-scripts/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "wokoo",
3 | "version": "0.3.3",
4 | "description": "create the basic project of tampermonkey",
5 | "author": "kinyaying ",
6 | "homepage": "",
7 | "license": "MIT",
8 | "main": "index.js",
9 | "directories": {
10 | "lib": "lib",
11 | "test": "__tests__"
12 | },
13 | "bin": {
14 | "wokoo": "./bin/www"
15 | },
16 | "files": [
17 | "lib",
18 | "modifyTemplate.js"
19 | ],
20 | "scripts": {
21 | "test": "echo \"Error: run tests from root\" && exit 1"
22 | },
23 | "gitHead": "074c60fcb699bbdba2f179efb50a60eb86e09f96",
24 | "dependencies": {
25 | "chalk": "^4.1.0",
26 | "commander": "^7.0.0",
27 | "consolidate": "^0.16.0",
28 | "cross-spawn": "^7.0.3",
29 | "ejs": "^3.1.5",
30 | "fs-extra": "^9.1.0",
31 | "inquirer": "^7.3.3",
32 | "metalsmith": "^2.3.0"
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/packages/wokoo-template/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/packages/wokoo-template/README.md:
--------------------------------------------------------------------------------
1 | # wokoo-template
2 |
3 | 是 wokoo 脚手架的模板部分,配合 [wokoo-scripts](https://www.npmjs.com/package/wokoo-scripts),用于初始化一个有基础配置的油猴项目。
4 |
5 | ## 功能
6 |
7 | - 提供 vue 和 react 的基本工程项目,根据用户选择生成指定基础项目
8 | - 提供基础的 webpack 配置
9 | - tampermonkey.txt 提供基本的油猴脚本配置
10 |
11 | ## 使用
12 |
13 | 1. 安装
14 |
15 | ```
16 | npm i wokoo -g
17 | ```
18 |
19 | 2. 创建项目
20 |
21 | ```
22 | wokoo my-plugin
23 | ```
24 |
25 | 3. 命令行中会弹出询问:
26 | ? which template do you prefer?
27 | [ ] react
28 | [ ] vue
29 | 4. 选择对应模板,生成初始化项目
30 |
31 | ## 使用到的库
32 |
33 | - vue
34 | - react
35 | - less
36 | - webpack
37 |
38 | ## 目录结构
39 |
40 | ```
41 | .
42 | ├── README.md
43 | ├── package-lock.json
44 | ├── package.json
45 | ├── public 公共资源
46 | │ ├── favicon.ico
47 | │ ├── icon.jpg
48 | │ └── index.html
49 | ├── react-template react模板
50 | │ ├── README.md
51 | │ ├── src
52 | │ │ ├── app.css
53 | │ │ ├── app.js
54 | │ │ └── index.js
55 | │ ├── tampermonkey.js 油猴插件基础配置文件
56 | │ ├── template.json
57 | │ └── webpack.config.base.js 针对react的webpack配置项
58 | ├── vue-template vue模板
59 | │ ├── README.md
60 | │ ├── src
61 | │ │ ├── app.less
62 | │ │ ├── app.vue
63 | │ │ └── index.js
64 | │ ├── tampermonkey.js 油猴插件基础配置文件
65 | │ ├── template.json
66 | │ └── webpack.config.base.js 针对vue的webpack配置项
67 | └── webpack.config.js
68 | ```
69 |
70 | ## 了解更多
71 |
72 | 如果想了解更多内容,请访问下面的网址:
73 | [油猴脚手架 wokoo 使用说明](https://juejin.cn/post/6922815205575491597)
74 | [油猴脚手架 wokoo git 仓库](https://github.com/kinyaying/wokoo)
75 |
--------------------------------------------------------------------------------
/packages/wokoo-template/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "wokoo-template",
3 | "version": "0.3.3",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "base64-js": {
8 | "version": "1.5.1",
9 | "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
10 | "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="
11 | },
12 | "bl": {
13 | "version": "4.0.3",
14 | "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.3.tgz",
15 | "integrity": "sha512-fs4G6/Hu4/EE+F75J8DuN/0IpQqNjAdC7aEQv7Qt8MHGUH7Ckv2MwTEEeN9QehD0pfIDkMI1bkHYkKy7xHyKIg==",
16 | "requires": {
17 | "buffer": "^5.5.0",
18 | "inherits": "^2.0.4",
19 | "readable-stream": "^3.4.0"
20 | }
21 | },
22 | "buffer": {
23 | "version": "5.7.1",
24 | "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
25 | "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
26 | "requires": {
27 | "base64-js": "^1.3.1",
28 | "ieee754": "^1.1.13"
29 | }
30 | },
31 | "cli-cursor": {
32 | "version": "3.1.0",
33 | "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
34 | "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
35 | "requires": {
36 | "restore-cursor": "^3.1.0"
37 | }
38 | },
39 | "cli-spinners": {
40 | "version": "2.5.0",
41 | "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.5.0.tgz",
42 | "integrity": "sha512-PC+AmIuK04E6aeSs/pUccSujsTzBhu4HzC2dL+CfJB/Jcc2qTRbEwZQDfIUpt2Xl8BodYBEq8w4fc0kU2I9DjQ=="
43 | },
44 | "clone": {
45 | "version": "1.0.4",
46 | "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
47 | "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4="
48 | },
49 | "defaults": {
50 | "version": "1.0.3",
51 | "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz",
52 | "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=",
53 | "requires": {
54 | "clone": "^1.0.2"
55 | }
56 | },
57 | "ieee754": {
58 | "version": "1.2.1",
59 | "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
60 | "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="
61 | },
62 | "inherits": {
63 | "version": "2.0.4",
64 | "resolved": "https://registry.npm.taobao.org/inherits/download/inherits-2.0.4.tgz",
65 | "integrity": "sha1-D6LGT5MpF8NDOg3tVTY6rjdBa3w="
66 | },
67 | "is-interactive": {
68 | "version": "1.0.0",
69 | "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz",
70 | "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w=="
71 | },
72 | "log-symbols": {
73 | "version": "4.0.0",
74 | "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz",
75 | "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==",
76 | "requires": {
77 | "chalk": "^4.0.0"
78 | },
79 | "dependencies": {
80 | "ansi-styles": {
81 | "version": "4.3.0",
82 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
83 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
84 | "requires": {
85 | "color-convert": "^2.0.1"
86 | }
87 | },
88 | "chalk": {
89 | "version": "4.1.0",
90 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
91 | "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
92 | "requires": {
93 | "ansi-styles": "^4.1.0",
94 | "supports-color": "^7.1.0"
95 | }
96 | },
97 | "color-convert": {
98 | "version": "2.0.1",
99 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
100 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
101 | "requires": {
102 | "color-name": "~1.1.4"
103 | }
104 | },
105 | "color-name": {
106 | "version": "1.1.4",
107 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
108 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
109 | },
110 | "has-flag": {
111 | "version": "4.0.0",
112 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
113 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
114 | },
115 | "supports-color": {
116 | "version": "7.2.0",
117 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
118 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
119 | "requires": {
120 | "has-flag": "^4.0.0"
121 | }
122 | }
123 | }
124 | },
125 | "mimic-fn": {
126 | "version": "2.1.0",
127 | "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
128 | "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="
129 | },
130 | "onetime": {
131 | "version": "5.1.2",
132 | "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
133 | "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
134 | "requires": {
135 | "mimic-fn": "^2.1.0"
136 | }
137 | },
138 | "ora": {
139 | "version": "5.2.0",
140 | "resolved": "https://registry.npmjs.org/ora/-/ora-5.2.0.tgz",
141 | "integrity": "sha512-+wG2v8TUU8EgzPHun1k/n45pXquQ9fHnbXVetl9rRgO6kjZszGGbraF3XPTIdgeA+s1lbRjSEftAnyT0w8ZMvQ==",
142 | "requires": {
143 | "bl": "^4.0.3",
144 | "chalk": "^4.1.0",
145 | "cli-cursor": "^3.1.0",
146 | "cli-spinners": "^2.5.0",
147 | "is-interactive": "^1.0.0",
148 | "log-symbols": "^4.0.0",
149 | "strip-ansi": "^6.0.0",
150 | "wcwidth": "^1.0.1"
151 | },
152 | "dependencies": {
153 | "ansi-regex": {
154 | "version": "5.0.0",
155 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
156 | "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg=="
157 | },
158 | "ansi-styles": {
159 | "version": "4.3.0",
160 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
161 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
162 | "requires": {
163 | "color-convert": "^2.0.1"
164 | }
165 | },
166 | "chalk": {
167 | "version": "4.1.0",
168 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
169 | "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
170 | "requires": {
171 | "ansi-styles": "^4.1.0",
172 | "supports-color": "^7.1.0"
173 | }
174 | },
175 | "color-convert": {
176 | "version": "2.0.1",
177 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
178 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
179 | "requires": {
180 | "color-name": "~1.1.4"
181 | }
182 | },
183 | "color-name": {
184 | "version": "1.1.4",
185 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
186 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
187 | },
188 | "has-flag": {
189 | "version": "4.0.0",
190 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
191 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
192 | },
193 | "strip-ansi": {
194 | "version": "6.0.0",
195 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
196 | "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
197 | "requires": {
198 | "ansi-regex": "^5.0.0"
199 | }
200 | },
201 | "supports-color": {
202 | "version": "7.2.0",
203 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
204 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
205 | "requires": {
206 | "has-flag": "^4.0.0"
207 | }
208 | }
209 | }
210 | },
211 | "readable-stream": {
212 | "version": "3.6.0",
213 | "resolved": "https://registry.npm.taobao.org/readable-stream/download/readable-stream-3.6.0.tgz",
214 | "integrity": "sha1-M3u9o63AcGvT4CRCaihtS0sskZg=",
215 | "requires": {
216 | "inherits": "^2.0.3",
217 | "string_decoder": "^1.1.1",
218 | "util-deprecate": "^1.0.1"
219 | }
220 | },
221 | "restore-cursor": {
222 | "version": "3.1.0",
223 | "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
224 | "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
225 | "requires": {
226 | "onetime": "^5.1.0",
227 | "signal-exit": "^3.0.2"
228 | }
229 | },
230 | "safe-buffer": {
231 | "version": "5.2.1",
232 | "resolved": "https://registry.npm.taobao.org/safe-buffer/download/safe-buffer-5.2.1.tgz",
233 | "integrity": "sha1-Hq+fqb2x/dTsdfWPnNtOa3gn7sY="
234 | },
235 | "signal-exit": {
236 | "version": "3.0.3",
237 | "resolved": "https://registry.npm.taobao.org/signal-exit/download/signal-exit-3.0.3.tgz",
238 | "integrity": "sha1-oUEMLt2PB3sItOJTyOrPyvBXRhw="
239 | },
240 | "string_decoder": {
241 | "version": "1.3.0",
242 | "resolved": "https://registry.npm.taobao.org/string_decoder/download/string_decoder-1.3.0.tgz",
243 | "integrity": "sha1-QvEUWUpGzxqOMLCoT1bHjD7awh4=",
244 | "requires": {
245 | "safe-buffer": "~5.2.0"
246 | }
247 | },
248 | "util-deprecate": {
249 | "version": "1.0.2",
250 | "resolved": "https://registry.npm.taobao.org/util-deprecate/download/util-deprecate-1.0.2.tgz",
251 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
252 | },
253 | "wcwidth": {
254 | "version": "1.0.1",
255 | "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz",
256 | "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=",
257 | "requires": {
258 | "defaults": "^1.0.3"
259 | }
260 | }
261 | }
262 | }
263 |
--------------------------------------------------------------------------------
/packages/wokoo-template/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "wokoo-template",
3 | "version": "0.3.3",
4 | "description": "provide the basic template for wokoo-scrits to create a tampermonkey project",
5 | "author": "kinyaying ",
6 | "homepage": "",
7 | "license": "ISC",
8 | "main": "index.js",
9 | "directories": {
10 | "lib": "lib",
11 | "test": "__tests__"
12 | },
13 | "files": [
14 | "react-template",
15 | "vue-template",
16 | "public",
17 | "webpack.config.js",
18 | ".gitignore"
19 | ],
20 | "scripts": {
21 | "test": "echo \"Error: run tests from root\" && exit 1"
22 | },
23 | "gitHead": "074c60fcb699bbdba2f179efb50a60eb86e09f96"
24 | }
25 |
--------------------------------------------------------------------------------
/packages/wokoo-template/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kinyaying/wokoo/2961afcb53c0e85dae8ec0f93b6f73fb0c9eb134/packages/wokoo-template/public/favicon.ico
--------------------------------------------------------------------------------
/packages/wokoo-template/public/icon.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kinyaying/wokoo/2961afcb53c0e85dae8ec0f93b6f73fb0c9eb134/packages/wokoo-template/public/icon.jpg
--------------------------------------------------------------------------------
/packages/wokoo-template/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/packages/wokoo-template/react-template/README.md:
--------------------------------------------------------------------------------
1 | ## <%=projectName%>
2 |
3 | 基于 wokoo 搭建的初始化工程,用于油猴插件开发。
4 |
5 | **基础配置:**
6 |
7 | - <%=basicProject%>
8 | - less
9 | - webpack
10 |
11 | ## 目录结构
12 |
13 | ```
14 | .
15 | ├── README.md 说明
16 | ├── package-lock.json
17 | ├── package.json
18 | ├── public 静态文件
19 | │ ├── favicon.ico
20 | │ ├── icon.jpg
21 | │ └── index.html html 文件
22 | ├── src
23 | │ ├── app.less
24 | │ ├── app.<% if(basicProject=='vue'){ %>vue<% } %><% if (basicProject=='react') { %>js<% } %>
25 | │ └── index.js 项目入口
26 | ├── tampermonkey.txt 油猴脚本入口文件
27 | ├── webpack.config.base.js
28 | └── webpack.config.js webpack 配置
29 | ```
30 |
31 | ## 开发
32 |
33 | **启动**
34 | 进入项目目录后,在命令行中输入:
35 |
36 | ```shell
37 | npm start
38 | ```
39 |
40 | **调试**
41 |
42 | 1. 打开浏览器,输入`localhost:8080`,查看页面展示是否正常。
43 | 2. 安装油猴插件
44 | 3. 打开油猴插件编辑界面,将 tampermonkey.txt 里的内容复制到编辑框中,保存。
45 | 4. 打开任意一个网页,比如`www.baidu.com`,
46 |
47 | - 查看油猴 icon 是否有一个 1 的数字标志,如果有说明油猴脚本已经成功激活
48 | - 网页的右上角会出现初始页面
49 |
50 | **构建**
51 |
52 | ```shell
53 | npm run build
54 | ```
55 |
56 | **发布插件到油猴市场**
57 |
58 | 油猴市场的优点是不用审核,即发即用,非常方便。
59 |
60 | 1. 将/dist/app.bundle.js 文件部署到 cdn 上,获取到对应 url。(可以放到 github 上,如果托管到 git 上最好做 cdn 加速)
61 | 2. 登录[油猴市场](https://greasyfork.org/),谷歌账号或 github 账号都可使用。
62 | 3. 点击账号名称,再点击**发布你编写的脚本**
63 | 4. 进入编辑页,将 tampermonkey.txt 里的内容复制到编辑框中,记得将里面的`localhost:8080`网址替换成静态资源 url
64 | 5. 点击 「发布脚本」即可
65 |
66 | ## 例子 demo
67 |
68 | 我已经使用 wokoo 脚手架开发了多个 demo,并发布到[油猴市场](https://greasyfork.org/),欢迎安装试用。
69 | [wokoo-demo](https://greasyfork.org/zh-CN/scripts/420327-wokoo-demo): 简单的示例插件
70 | [zhihu-helper](https://greasyfork.org/zh-CN/scripts/421238-zhihu-helper): 知乎目录
71 | [MoveSearch](https://greasyfork.org/zh-CN/scripts/420327-MoveSearch): 划词搜索,默认搜[开发者搜索](http://kaifa.baidu.com)
72 |
73 | [快速上手油猴插件开发(实战篇)](https://juejin.cn/post/6925605904561750030) 详细写了开发过程
74 |
75 | ## 了解更多
76 |
77 | 如果想了解更多内容,请访问下面的网址:
78 | [油猴脚手架 wokoo 使用说明](https://juejin.cn/post/6922815205575491597)
79 | [油猴脚手架 wokoo git 仓库](https://github.com/kinyaying/wokoo)
80 |
--------------------------------------------------------------------------------
/packages/wokoo-template/react-template/src/app.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import './app.less'
3 | import logo from '../public/icon.jpg'
4 | export default class extends React.Component {
5 | constructor(props) {
6 | super(props)
7 | this.state = { show: true }
8 | }
9 | handleClose() {
10 | this.setState({
11 | show: !this.state.show,
12 | })
13 | }
14 | render() {
15 | let { show } = this.state
16 | return (
17 | <>
18 | {show ? (
19 |
41 | ) : (
42 |
43 |

44 | open
45 |
46 | )}
47 | >
48 | )
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/packages/wokoo-template/react-template/src/app.less:
--------------------------------------------------------------------------------
1 | .Wokoo {
2 | position: absolute;
3 | text-align: center;
4 | width: 400px;
5 | height: 400px;
6 | top: 0;
7 | right: 0;
8 | z-index: 999;
9 | }
10 | .Wokoo-logo {
11 | height: 30vmin;
12 | border-radius: 50%;
13 | pointer-events: none;
14 | }
15 | @media (prefers-reduced-motion: no-preference) {
16 | .Wokoo-logo {
17 | animation: Wokoo-app-logo-spin infinite 20s linear;
18 | }
19 | }
20 |
21 | .Wokoo-header {
22 | background-color: #6c4d25;
23 | display: flex;
24 | flex-direction: column;
25 | align-items: center;
26 | justify-content: center;
27 | font-size: calc(10px + 2vmin);
28 | color: white;
29 | height: 100%;
30 | }
31 |
32 | .Wokoo-link {
33 | color: #efb61c;
34 | }
35 | .Wokoo-close-icon {
36 | position: absolute;
37 | top: 10px;
38 | right: 10px;
39 | cursor: pointer;
40 | }
41 | .Wokoo-hide {
42 | position: absolute;
43 | text-align: center;
44 | width: 100px;
45 | height: 40px;
46 | background-color: #6c4d25;
47 | top: 0;
48 | right: 0;
49 | z-index: 999;
50 | display: flex;
51 | align-items: center;
52 | justify-content: center;
53 | color: #fff;
54 | cursor: pointer;
55 | }
56 | .Wokoo-hide-logo {
57 | width: 30px;
58 | height: 30px;
59 | border-radius: 50%;
60 | margin-right: 10px;
61 | }
62 |
63 | @keyframes Wokoo-app-logo-spin {
64 | from {
65 | transform: rotate(0deg);
66 | }
67 | to {
68 | transform: rotate(360deg);
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/packages/wokoo-template/react-template/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import ReactDOM from 'react-dom'
3 | import App from './app'
4 |
5 | const wokooApp = document.createElement('div')
6 | wokooApp.id = 'wokooApp-<%=projectName%>-<%=randomNumber%>'
7 | document.body.appendChild(wokooApp)
8 | ReactDOM.render(, wokooApp)
9 |
--------------------------------------------------------------------------------
/packages/wokoo-template/react-template/tampermonkey.js:
--------------------------------------------------------------------------------
1 | // ==UserScript==
2 | // @name <%=projectName%>
3 | // @namespace http://tampermonkey.net/
4 | // @version <%=version%>
5 | // @description try to take over the world!
6 | // @author
7 | // @match https://*/*
8 | // @match http://*/*
9 |
10 | // ==/UserScript==
11 |
12 | ;(function () {
13 | 'use strict'
14 | if (location.href === 'http://localhost:8080/') return
15 | var script = document.createElement('script')
16 | script.src = 'http://localhost:8080/app.bundle.js'
17 | document.body.appendChild(script)
18 | })()
19 |
--------------------------------------------------------------------------------
/packages/wokoo-template/react-template/template.json:
--------------------------------------------------------------------------------
1 | {
2 | "package": {
3 | "dependencies": {
4 | "react": "^17.0.1",
5 | "react-dom": "^17.0.1",
6 | "@babel/core": "^7.12.10",
7 | "@babel/preset-react": "^7.12.10",
8 | "babel-loader": "^8.2.2"
9 | },
10 | "devDependencies": {
11 | "@babel/plugin-proposal-class-properties": "^7.12.1",
12 | "@babel/plugin-proposal-decorators": "^7.12.12",
13 | "@babel/preset-env": "^7.12.11",
14 | "cross-env": "^7.0.3",
15 | "css-loader": "^5.0.1",
16 | "file-loader": "^6.2.0",
17 | "html-webpack-plugin": "^5.0.0",
18 | "less": "^4.1.0",
19 | "less-loader": "^8.0.0",
20 | "style-loader": "^2.0.0",
21 | "url-loader": "^4.1.1",
22 | "webpack": "^5.20.2",
23 | "webpack-cli": "^4.5.0",
24 | "webpack-dev-server": "^3.11.2",
25 | "webpack-merge": "^5.7.3"
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/packages/wokoo-template/react-template/webpack.config.base.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | entry: {
3 | app: '/src/index.js',
4 | },
5 | module: {
6 | rules: [
7 | {
8 | test: /\.(js|jsx)$/, //匹配js文件
9 | use: {
10 | loader: 'babel-loader',
11 | options: {
12 | presets: ['@babel/preset-react', '@babel/preset-env'],
13 | plugins: [
14 | ['@babel/plugin-proposal-decorators', { legacy: true }],
15 | ['@babel/plugin-proposal-class-properties', { loose: true }],
16 | ['@babel/plugin-proposal-private-methods', { loose: true }],
17 | ['@babel/plugin-proposal-private-property-in-object', { loose: true }]
18 | ],
19 | },
20 | },
21 | },
22 | ],
23 | },
24 | }
25 |
--------------------------------------------------------------------------------
/packages/wokoo-template/vue-template/README.md:
--------------------------------------------------------------------------------
1 | ## <%=projectName%>
2 |
3 | 基于 wokoo 搭建的初始化工程,用于油猴插件开发。
4 |
5 | **基础配置:**
6 |
7 | - <%=basicProject%>
8 | - less
9 | - webpack
10 |
11 | ## 目录结构
12 |
13 | ```
14 | .
15 | ├── README.md 说明
16 | ├── package-lock.json
17 | ├── package.json
18 | ├── public 静态文件
19 | │ ├── favicon.ico
20 | │ ├── icon.jpg
21 | │ └── index.html html 文件
22 | ├── src
23 | │ ├── app.less
24 | │ ├── app.<% if(basicProject=='vue'){ %>vue<% } %><% if (basicProject=='react') { %>js<% } %>
25 | │ └── index.js 项目入口
26 | ├── tampermonkey.txt 油猴脚本入口文件
27 | ├── webpack.config.base.js
28 | └── webpack.config.js webpack 配置
29 | ```
30 |
31 | ## 开发
32 |
33 | **启动**
34 | 进入项目目录后,在命令行中输入:
35 |
36 | ```shell
37 | npm start
38 | ```
39 |
40 | **调试**
41 |
42 | 1. 打开浏览器,输入`localhost:8080`,查看页面展示是否正常。
43 | 2. 安装油猴插件
44 | 3. 打开油猴插件编辑界面,将 tampermonkey.txt 里的内容复制到编辑框中,保存。
45 | 4. 打开任意一个网页,比如`www.baidu.com`,
46 |
47 | - 查看油猴 icon 是否有一个 1 的数字标志,如果有说明油猴脚本已经成功激活
48 | - 网页的右上角会出现初始页面
49 |
50 | **构建**
51 |
52 | ```shell
53 | npm run build
54 | ```
55 |
56 | **发布插件到油猴市场**
57 |
58 | 油猴市场的优点是不用审核,即发即用,非常方便。
59 |
60 | 1. 将/dist/app.bundle.js 文件部署到 cdn 上,获取到对应 url。(可以放到 github 上,如果托管到 git 上最好做 cdn 加速)
61 | 2. 登录[油猴市场](https://greasyfork.org/),谷歌账号或 github 账号都可使用。
62 | 3. 点击账号名称,再点击**发布你编写的脚本**
63 | 4. 进入编辑页,将 tampermonkey.txt 里的内容复制到编辑框中,记得将里面的`localhost:8080`网址替换成静态资源 url
64 | 5. 点击 「发布脚本」即可
65 |
66 | ## 例子 demo
67 |
68 | 我已经使用 wokoo 脚手架开发了多个 demo,并发布到[油猴市场](https://greasyfork.org/),欢迎安装试用。
69 | [wokoo-demo](https://greasyfork.org/zh-CN/scripts/420327-wokoo-demo): 简单的示例插件
70 | [zhihu-helper](https://greasyfork.org/zh-CN/scripts/421238-zhihu-helper): 知乎目录
71 | [MoveSearch](https://greasyfork.org/zh-CN/scripts/420327-MoveSearch): 划词搜索,默认搜[开发者搜索](http://kaifa.baidu.com)
72 |
73 | [快速上手油猴插件开发(实战篇)](https://juejin.cn/post/6925605904561750030) 详细写了开发过程
74 |
75 | ## 了解更多
76 |
77 | 如果想了解更多内容,请访问下面的网址:
78 | [油猴脚手架 wokoo 使用说明](https://juejin.cn/post/6922815205575491597)
79 | [油猴脚手架 wokoo git 仓库](https://github.com/kinyaying/wokoo)
80 |
--------------------------------------------------------------------------------
/packages/wokoo-template/vue-template/src/app.less:
--------------------------------------------------------------------------------
1 | .Wokoo {
2 | position: absolute;
3 | text-align: center;
4 | width: 400px;
5 | height: 400px;
6 | top: 0;
7 | right: 0;
8 | z-index: 999;
9 | }
10 | .Wokoo-logo {
11 | height: 30vmin;
12 | border-radius: 50%;
13 | pointer-events: none;
14 | }
15 | @media (prefers-reduced-motion: no-preference) {
16 | .Wokoo-logo {
17 | animation: Wokoo-app-logo-spin infinite 20s linear;
18 | }
19 | }
20 |
21 | .Wokoo-header {
22 | background-color: #6c4d25;
23 | display: flex;
24 | flex-direction: column;
25 | align-items: center;
26 | justify-content: center;
27 | font-size: calc(10px + 2vmin);
28 | color: white;
29 | height: 100%;
30 | }
31 |
32 | .Wokoo-link {
33 | color: #efb61c;
34 | }
35 | .Wokoo-close-icon {
36 | position: absolute;
37 | top: 10px;
38 | right: 10px;
39 | cursor: pointer;
40 | }
41 | .Wokoo-hide {
42 | position: absolute;
43 | text-align: center;
44 | width: 100px;
45 | height: 40px;
46 | background-color: #6c4d25;
47 | top: 0;
48 | right: 0;
49 | z-index: 999;
50 | display: flex;
51 | align-items: center;
52 | justify-content: center;
53 | color: #fff;
54 | cursor: pointer;
55 | }
56 | .Wokoo-hide-logo {
57 | width: 30px;
58 | height: 30px;
59 | border-radius: 50%;
60 | margin-right: 10px;
61 | }
62 |
63 | @keyframes Wokoo-app-logo-spin {
64 | from {
65 | transform: rotate(0deg);
66 | }
67 | to {
68 | transform: rotate(360deg);
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/packages/wokoo-template/vue-template/src/app.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
23 |
24 |
25 |
![logo]()
26 | open
27 |
28 |
29 |
46 |
48 |
--------------------------------------------------------------------------------
/packages/wokoo-template/vue-template/src/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './app.vue'
3 |
4 | const wokooApp = document.createElement('div')
5 | wokooApp.id = 'wokooApp-<%=projectName%>-<%=randomNumber%>'
6 | document.body.appendChild(wokooApp)
7 | const vm = new Vue({
8 | el: wokooApp,
9 | render: (h) => h(App),
10 | })
11 |
--------------------------------------------------------------------------------
/packages/wokoo-template/vue-template/tampermonkey.js:
--------------------------------------------------------------------------------
1 | // ==UserScript==
2 | // @name <%=projectName%>
3 | // @namespace http://tampermonkey.net/
4 | // @version <%=version%>
5 | // @description try to take over the world!
6 | // @author
7 | // @match https://*/*
8 | // @match http://*/*
9 |
10 | // ==/UserScript==
11 |
12 | ;(function () {
13 | 'use strict'
14 | if (location.href === 'http://localhost:8080/') return
15 | var script = document.createElement('script')
16 | script.src = 'http://localhost:8080/app.bundle.js'
17 | document.body.appendChild(script)
18 | })()
19 |
--------------------------------------------------------------------------------
/packages/wokoo-template/vue-template/template.json:
--------------------------------------------------------------------------------
1 | {
2 | "package": {
3 | "dependencies": {
4 | "vue": "^2.6.12",
5 | "vue-loader": "^15.9.6",
6 | "vue-template-compiler": "^2.6.12"
7 | },
8 | "devDependencies": {
9 | "css-loader": "^5.0.1",
10 | "file-loader": "^6.2.0",
11 | "html-webpack-plugin": "^5.0.0",
12 | "less": "^4.1.0",
13 | "less-loader": "^8.0.0",
14 | "style-loader": "^2.0.0",
15 | "url-loader": "^4.1.1",
16 | "vue-loader": "^15.9.6",
17 | "webpack": "^5.20.2",
18 | "webpack-cli": "^4.5.0",
19 | "webpack-dev-server": "^3.11.2",
20 | "webpack-merge": "^5.7.3",
21 | "cross-env": "^7.0.3"
22 | }
23 | }
24 | }
--------------------------------------------------------------------------------
/packages/wokoo-template/vue-template/webpack.config.base.js:
--------------------------------------------------------------------------------
1 | const VueLoaderPlugin = require('vue-loader/lib/plugin')
2 |
3 | module.exports = {
4 | entry: {
5 | app: '/src/index.js',
6 | },
7 | module: {
8 | rules: [
9 | {
10 | test: /\.vue$/,
11 | loader: 'vue-loader',
12 | },
13 | ],
14 | },
15 | plugins: [new VueLoaderPlugin()],
16 | }
17 |
--------------------------------------------------------------------------------
/packages/wokoo-template/webpack.config.js:
--------------------------------------------------------------------------------
1 | const HtmlWebpackPlugin = require('html-webpack-plugin')
2 | const { merge } = require('webpack-merge')
3 | const base = require('./webpack.config.base')
4 |
5 | module.exports = merge(base, {
6 | mode: process.env.NODE_ENV || 'production',
7 | devtool: 'source-map',
8 | output: {
9 | filename: '[name].bundle.js',
10 | path: __dirname + '/dist',
11 | },
12 | module: {
13 | rules: [
14 | {
15 | test: /\.(less|css)$/,
16 | use: ['style-loader', 'css-loader', 'less-loader'],
17 | },
18 | {
19 | test: /\.(woff|woff2|eot|ttf|otf|png|svg|jpg|gif)$/,
20 | use: {
21 | loader: 'url-loader',
22 | options: {
23 | limit: 20480,
24 | },
25 | },
26 | },
27 | ],
28 | },
29 | plugins: [
30 | new HtmlWebpackPlugin({
31 | template: './public/index.html',
32 | }),
33 | ],
34 | })
35 |
--------------------------------------------------------------------------------