Skip to content

Commit 5f19859

Browse files
committed
feat(server): support app init command
1 parent 9444c70 commit 5f19859

File tree

2 files changed

+120
-50
lines changed

2 files changed

+120
-50
lines changed

README.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,13 @@ once started, the server will listen to changes in the app template source files
1919
when a change is detected, it will re-compile the template to an output directory, allowing live inspection of the
2020
generated vue.js application.
2121

22+
after the output project is generated, if it's an NPM project, the server will collect its dependencies with `npm i`,
23+
and run `npm run dev` (you can customize which command will run instead of `dev`).
24+
2225

2326
## setup
2427

25-
- install via npm:
28+
- install via NPM:
2629

2730
```sh
2831
npm i vue-cli-template-dev-server -D
@@ -76,6 +79,12 @@ npm run dev -- 'dist/dev-server-out' 'my-app'
7679
}
7780
```
7881

82+
you can also change which NPM script will run on startup (`dev` by default), by passing the
83+
`TARGET_INIT_COMMAND` environment variable:
84+
85+
```sh
86+
env TARGET_INIT_COMMAND='serve' npm run dev -- 'dist/dev-server-out' 'my-app'
87+
```
7988

8089

8190
## demo

bin/server.sh

Lines changed: 110 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ function usage {
66
usage
77
-----
88
9-
[env TEMPLATE_PROJECT_DIR="$(npm prefix)"] vue-cli-template-dev-server.sh [<output_dir>] [<output_project_name>] [-h]
9+
[env SOURCE_DIR="$(npm prefix)" TARGET_INIT_COMMAND="dev"] vue-cli-template-dev-server.sh [-h] [<target-dir>] [<project-name>]
1010
1111
''
1212
'
@@ -17,34 +17,50 @@ function info {
1717
overview
1818
--------
1919
20-
watch source files of a vue.js custom template project, and triggers the vue-cli init to rebuild the project.
20+
watches source files of a vue-cli custom template project, and triggers the vue-cli init command to rebuild the project.
2121
to be used while developing custom templates.
2222
2323
24-
environment
25-
-----------
24+
flags
25+
-----
2626
27-
TEMPLATE_PROJECT_DIR
28-
the local path of the vue-init custom template project to watch.
29-
defaults to "$(npm prefix)".
27+
-h
28+
shows this help page, and quits.
3029
3130
32-
arguments
33-
---------
31+
operands
32+
--------
3433
35-
output_dir
36-
a local path of the desired directory to pour the generated project into.
34+
target-dir
35+
a path, relative to the custom template project root, of a directory to pour the generated files into.
3736
the generated project will be created as a child directory of that path.
38-
defaults to "${TEMPLATE_PROJECT_DIR}/out".
37+
defaults to "${SOURCE_DIR}/out".
3938
40-
output_project_name
41-
a name for the directory of the project that will be generated by vue init.
39+
project-name
40+
a name for the generated project directory, which will be nested inside the target directory.
4241
defaults to "awesome-vue-app".
4342
43+
44+
environment
45+
-----------
46+
47+
SOURCE_DIR
48+
the local path of the custom template project to watch.
49+
defaults to "$(npm prefix)" (the host NPM project).
50+
51+
TARGET_INIT_COMMAND
52+
the name of an NPM script command in the output project, to be run once it is generated, right after installing its dependencies.
53+
defaults to "dev".
54+
4455
''
4556
'
4657
}
4758

59+
# todo - make this phase 2!
60+
#echo '----------------------'
61+
#echo "${npm_package_config_initCommand:-dev}"
62+
#echo '----------------------'
63+
4864
function main {
4965
if [[ "$@" =~ '-h' ]]; then
5066
info
@@ -59,34 +75,41 @@ function main {
5975
function start {
6076
local temp_dir
6177
local expect_file
62-
local output_dir="${1:-${TEMPLATE_PROJECT_DIR}/out}"
63-
local output_project_name="${2:-awesome-vue-app}"
78+
# todo - is this default working properly in all cases? test it
79+
local target_dir="${1:-${SOURCE_DIR}/out}"
80+
local target_project_name="${2:-awesome-vue-app}"
6481

65-
output_dir="$(abs_path "$output_dir")"
82+
target_dir="$(abs_path "$target_dir")"
6683
temp_dir="$(create_temp_dir)"
6784
expect_file="${temp_dir}/vue-init.exp"
6885

6986
set_traps "$temp_dir"
7087

88+
# todo - cleanup output dir before everything
89+
7190
log 'hi :)'
7291

7392
log 'starting vue init survey...'
74-
start_auto_survey ${output_dir} ${expect_file} ${TEMPLATE_PROJECT_DIR} "${output_project_name}"
75-
log 'project generated using provided answers'
76-
log 'waiting for changes...'
93+
start_auto_survey ${target_dir} ${expect_file} ${SOURCE_DIR} "${target_project_name}"
94+
log 'output project generated using provided answers'
95+
log 'initializing output project...'
96+
initialize_target_project ${target_dir}/${target_project_name} "$TARGET_INIT_COMMAND"
97+
log 'output project initialized'
7798

78-
fswatch -o "${TEMPLATE_PROJECT_DIR}/template" | while read num; do
99+
log 'waiting for changes...'
100+
fswatch -o "${SOURCE_DIR}/template" | while read num; do
79101
log 'change detected'
80102
log 'auto-generating output project...'
81-
start_survey ${output_dir} ${expect_file}
82-
log 'project regenerated using initial answers'
103+
start_survey ${target_dir} ${expect_file}
104+
log 'output project regenerated using initial answers'
83105
log 'waiting for changes...'
84106
done
85107
}
86108

87109
function setup_environment {
88-
validate_template_project_dir
89-
ensure_template_project_dir
110+
validate_source_dir
111+
ensure_source_dir
112+
ensure_target_init_command
90113
}
91114

92115
function ensure_dependencies {
@@ -97,15 +120,15 @@ function ensure_dependencies {
97120
function start_auto_survey {
98121
local work_dir="$1"
99122
local expect_file="$2"
100-
local template_project_dir="$3"
101-
local output_project_name="$4"
123+
local source_dir="$3"
124+
local target_project_name="$4"
102125

103126
# create a directory to force vue-init to ask about overwriting the directory on the first time
104-
ensure_dir "${work_dir}/$output_project_name"
127+
ensure_dir "${work_dir}/$target_project_name"
105128

106129
pushd ${work_dir} >/dev/null 2>&1
107130
# this will generate an expect file, all filled with answers to the vue-init survey questions
108-
autoexpect -quiet -f ${expect_file} vue init ${template_project_dir} "${output_project_name}"
131+
autoexpect -quiet -f ${expect_file} vue init ${source_dir} "${target_project_name}"
109132
popd >/dev/null 2>&1
110133

111134
search_line ${expect_file} 'expect -exact.*'
@@ -121,6 +144,31 @@ function start_auto_survey {
121144
chmod u+x ${expect_file}
122145
}
123146

147+
function initialize_target_project {
148+
local project_dir="$1"
149+
local init_command="$2"
150+
151+
if is_npm_repo "$project_dir"; then
152+
pushd ${project_dir} >/dev/null 2>&1
153+
154+
# install dependencies
155+
npm i >/dev/null 2>&1
156+
if (( $? == 1 )); then
157+
quit "failed installing the output project's npm dependencies"
158+
fi
159+
160+
# launch dev server / whatever
161+
if is_npm_command_available "$init_command"; then
162+
npm run "$init_command" >/dev/null 2>&1
163+
if (( $? == 1 )); then
164+
quit "the output project's initialize command execution failed"
165+
fi
166+
fi
167+
168+
popd >/dev/null 2>&1
169+
fi
170+
}
171+
124172
function start_survey {
125173
local work_dir="$1"
126174
local expect_file="$2"
@@ -130,30 +178,32 @@ function start_survey {
130178
popd >/dev/null 2>&1
131179
}
132180

133-
function validate_template_project_dir {
134-
if [[ -n "$TEMPLATE_PROJECT_DIR" ]]; then
135-
if [[ ! -d "$TEMPLATE_PROJECT_DIR" ]]; then
136-
quit '$TEMPLATE_PROJECT_DIR is not a directory'
181+
function validate_source_dir {
182+
if [[ -n "$SOURCE_DIR" ]]; then
183+
if [[ ! -d "$SOURCE_DIR" ]]; then
184+
quit '$SOURCE_DIR is not a directory'
137185
fi
138-
if ! is_npm_repo "${TEMPLATE_PROJECT_DIR}"; then
139-
quit '$TEMPLATE_PROJECT_DIR is not an npm project'
186+
if ! is_npm_repo "${SOURCE_DIR}"; then
187+
quit '$SOURCE_DIR is not an npm project'
140188
fi
141189
else
142-
# we know that npm_host_path will be the default value in case
143-
# $TEMPLATE_PROJECT_DIR is empty.
190+
# we know that npm_host_path will be the default value in case $SOURCE_DIR is empty.
144191
if [[ -z "$(npm_host_path)" ]]; then
145192
quit 'could not resolve npm host'
146193
fi
147194
fi
148195
}
149196

150-
function ensure_template_project_dir {
151-
TEMPLATE_PROJECT_DIR="${TEMPLATE_PROJECT_DIR:-$(npm_host_path)}"
152-
TEMPLATE_PROJECT_DIR="${TEMPLATE_PROJECT_DIR:+$(abs_path "$TEMPLATE_PROJECT_DIR")}"
197+
function ensure_source_dir {
198+
SOURCE_DIR="${SOURCE_DIR:-$(npm_host_path)}"
199+
SOURCE_DIR="${SOURCE_DIR:+$(abs_path "$SOURCE_DIR")}"
200+
}
201+
202+
function ensure_target_init_command {
203+
TARGET_INIT_COMMAND="${TARGET_INIT_COMMAND:-dev}"
153204
}
154205

155206
function npm_host_path {
156-
local path
157207
local npm_prefix="$(npm prefix)"
158208
if is_npm_repo "$npm_prefix"; then
159209
printf "%s" "$npm_prefix"
@@ -164,11 +214,12 @@ function npm_host_path {
164214

165215
function is_npm_repo {
166216
local dir="$1"
167-
if [[ -f "${dir}/package.json" ]]; then
168-
return 0
169-
else
170-
return 1
171-
fi
217+
is_file "${dir}/package.json"
218+
}
219+
220+
function is_npm_command_available {
221+
local cmd="$1"
222+
[[ -n "$cmd" && -n "$(npm run --parseable | grep '^'"$cmd"':')" ]]
172223
}
173224

174225
function abs_path {
@@ -177,12 +228,22 @@ function abs_path {
177228
}
178229

179230
function ensure_dir {
180-
local dir="$1"
181-
if [[ ! -d "$dir" ]]; then
182-
mkdir -p "$dir"
231+
local path="$1"
232+
if ! is_dir "$path"; then
233+
mkdir -p "$path"
183234
fi
184235
}
185236

237+
function is_file {
238+
local path="$1"
239+
[[ -n "$path" && -f "$path" ]]
240+
}
241+
242+
function is_dir {
243+
local path="$1"
244+
[[ -n "$path" && -d "$path" ]]
245+
}
246+
186247
function remove_dir {
187248
rm -rf "$@" >/dev/null 2>&1
188249
}

0 commit comments

Comments
 (0)