diff --git a/.gitignore b/.gitignore index 9e608e2..8b2c2af 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +*.todo .history/ .idea/ dist/css/ diff --git a/.vscode/icons/icon-js.png b/.vscode/icons/icon-js.png deleted file mode 100644 index 45e5381..0000000 Binary files a/.vscode/icons/icon-js.png and /dev/null differ diff --git a/.vscode/icons/icon-sass.png b/.vscode/icons/icon-sass.png deleted file mode 100644 index 53265c2..0000000 Binary files a/.vscode/icons/icon-sass.png and /dev/null differ diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 52c33c7..45fdfe0 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -5,14 +5,14 @@ "tasks": [ { "label": "Gulp: build", - "type": "shell", - "command": "gulp build", + "type": "gulp", + "task": "build", "problemMatcher": [], }, { "label": "Gulp: dev", - "type": "shell", - "command": "gulp dev", + "type": "gulp", + "task": "dev", "problemMatcher": [], "group": { "kind": "build", diff --git a/README.md b/README.md index 80bde60..e30b6a5 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # SSP ยป Simple Starter Pack -Simple HTML5 + (S)CSS + JS starter pack (boilerplate) with pre-configured usefull tools & libraries: +Simple HTML5 + (S)CSS + TypeScript starter pack (boilerplate) with pre-configured usefull tools & libraries: - Live reload & sync (using [Browsersync](https://browsersync.io/)) - SCSS compile with autoprefixer, sourcemaps and minification -- JS compile (using [Babel](https://babeljs.io/)) with sourcemaps and minification +- TypeScript compile (using [Webpack](https://webpack.js.org/) and [Babel](https://babeljs.io/)) with sourcemaps and minification - JPG / PNG / GIF images optimization (with imagemin) - SVG optimization (with SVGO) - Predefined tasks for VSCode editor @@ -23,12 +23,15 @@ git clone https://github.com/PixelT/SimpleStarterPack.git path/to/your/project cd path/to/your/project yarn install ``` +## Gulp tasks +- `gulp` or `gulp build` - it compiles & minifies SCSS and TypeScript, sourcemaps are disabled. +- `gulp dev` - it runs Browsersync in developer mode, with sourcemaps enabled. -## Additional information -It's possible to pass to Browsersync custom settings, by adding additional arguments into `gulp dev` task: -- `--proxy="your_proxy_address"` - custom proxy URL address (default is `.test`) -- `--port="your_port"` - custom port (default is `3000`) +## Static vs Dynamic sites +By default, SSP are using `html` file(s) and run in `server` mode - no action is needed here. +If you have already running local PHP server (MAMP / XAMP / WAMP etc.) you can use `dynamic` mode - change index.html to index.php and run `gulp dev` task with `--proxy` argument (see below) -## Gulp tasks -- `gulp` or `gulp build` - it compiles & minifies SCSS and JS, sourcemaps are disabled. -- `gulp dev` - it runs Browsersync with sourcemaps enabled. \ No newline at end of file +## Pass custom settings +It's possible to pass to Browsersync custom settings, by adding additional arguments into `gulp dev` task: +- `--proxy` or `--proxy="your_proxy_address"` - custom proxy URL address (default is `.test`) +- `--port="your_port"` - custom port for `proxy` (default is `3000`) \ No newline at end of file diff --git a/gulpfile.js b/gulpfile.js index 74165c6..7bdc627 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -15,25 +15,36 @@ const proxy = ($.yargs.argv.proxy) ? $.yargs.argv.proxy : false; let folderPath = (process.platform === 'darwin') ? __dirname.split('/') : __dirname.split('\\'); folderPath = folderPath[folderPath.length-1].replace(/([A-Z:\\]*[_]+)/g, ''); + $.gulp.task('browserSync', () => { + const static = { + baseDir: "./", + serveStaticOptions: { + extensions: ["html"] + } + } + const dynamic = (typeof proxy === 'string' || proxy instanceof String) ? proxy : folderPath + '.test'; + const serverMode = proxy ? 'proxy' : 'server'; + return $.browserSync.init({ - proxy: proxy || folderPath + '.test', + [serverMode]: serverMode === 'proxy' ? dynamic : static, port: port, notify: true, - open: false + open: false, + logPrefix: "SimpleStarterPack", }); }); + $.gulp.task('compileScss', () => { return $.gulp.src('src/scss/style.scss') .pipe($.plumber({ errorHandler (err) { - $.notify.onError({ - title: (err) => `${err.file.replace(`${process.cwd()}/`, '')}:${err.line}:${err.column}`, - message: (err) => err.messageOriginal.trim(), - icon: $.path.join(__dirname, ".vscode/icons/icon-sass.png"), - sound: 'Frog', - })(err) + $.nodeNotifier.notify({ + title: `SCSS error in:`, + message: `${err.file.replace(`${process.cwd()}/`, '')}:${err.line}:${err.column}`, + sound: true, + }); this.emit('end'); } })) @@ -45,29 +56,31 @@ $.gulp.task('compileScss', () => { .pipe($.browserSync.stream({ match: '**/*.css' })) }); -$.gulp.task('compileJs', () => { - return $.gulp.src('src/js/**/*.js') - .pipe($.plumber({ - errorHandler (err) { - $.notify.onError({ - title: (err) => `${err.fileName.replace(`${process.cwd()}/`, '')}:${err.loc.line}:${err.loc.column}`, - message: (err) => `${err.message.split('\n')[0].replace(`${err.fileName}: `, '')}`.trim(), - icon: $.path.join(__dirname, ".vscode/icons/icon-js.png"), - sound: 'Frog', - })(err) - this.emit('end'); - } - })) - .pipe($.if(isDev, $.sourcemaps.init())) - .pipe($.babel({ - presets: ['@babel/env'] + +$.gulp.task('compileTs', () => { + return $.gulp.src('src/js/app.ts') + .pipe($.plumber()) + .pipe($.webpackStream({ + mode: 'none', + module: { rules: [{ test: /\.tsx?$/, use: 'ts-loader', exclude: /node_modules/, }], }, + output: { filename: 'app.js', }, + resolve: { extensions: ['.js', '.jsx', '.ts', '.tsx'], }, + }, null, (err, stats) => { + if (stats.compilation.errors.length >= 1) { + const errorMessage = stats.compilation.errors[0].message.replace(/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g, ''); + const path = errorMessage.split('\n')[0].replace(/\[tsl\] ERROR in/, '').replace(`${process.cwd()}/`, '').replace('(', '').replace(',' ,':').replace(')', ''); + + $.nodeNotifier.notify({ + title: `TS error in:`, + message: `${path}`, + sound: true + }); + } })) - .pipe($.uglify()) - .pipe($.if(isDev, $.sourcemaps.write())) .pipe($.gulp.dest('dist/js')) - .pipe($.browserSync.stream({match: '**/*.js'})) }); + $.gulp.task('optimizeImages', () => { return $.gulp.src('src/images/**/*.{png,gif,jpg}') .pipe($.plumber()) @@ -78,6 +91,7 @@ $.gulp.task('optimizeImages', () => { .pipe($.browserSync.stream({match: '**/*.{png,gif,jpg}'})) }); + $.gulp.task('optimizeSVG', () => { return $.gulp.src('src/images/**/*.svg') .pipe($.plumber()) @@ -86,15 +100,18 @@ $.gulp.task('optimizeSVG', () => { .pipe($.browserSync.stream({match: '**/*.svg'})) }) + $.gulp.task('watch', $.gulp.parallel(['browserSync'], () => { $.gulp.watch(['**/*.php', '**/*.html'], {cwd:'./'}).on('change', $.browserSync.reload); - $.gulp.watch('src/js/**/*.js', {cwd: './'}, $.gulp.parallel(['compileJs'])); + $.gulp.watch('src/js/**/*.ts', {cwd: './'}, $.gulp.parallel(['compileTs'])).on('change', $.browserSync.reload); $.gulp.watch('src/scss/**/*.scss', {cwd: './'}, $.gulp.parallel(['compileScss'])); $.gulp.watch('src/images/**/*.{png,gif,jpg}', {cwd: './'}, $.gulp.parallel(['optimizeImages'])); $.gulp.watch('src/images/**/*.svg', {cwd: './'}, $.gulp.parallel(['optimizeSVG'])); })); -$.gulp.task('dev', $.gulp.series('compileScss', 'compileJs', $.gulp.parallel('optimizeImages', 'optimizeSVG'), 'watch')); -$.gulp.task('build', $.gulp.series('compileScss', 'compileJs', $.gulp.parallel('optimizeImages', 'optimizeSVG'))); + +$.gulp.task('dev', $.gulp.series('compileScss', 'compileTs', $.gulp.parallel('optimizeImages', 'optimizeSVG'), 'watch')); +$.gulp.task('build', $.gulp.series('compileScss', 'compileTs', $.gulp.parallel('optimizeImages', 'optimizeSVG'))); + $.gulp.task('default', $.gulp.series(['build'])); \ No newline at end of file diff --git a/index.php b/index.html similarity index 85% rename from index.php rename to index.html index 27f28c1..23264d5 100644 --- a/index.php +++ b/index.html @@ -5,7 +5,7 @@ - + Simple Starter Pack diff --git a/package.json b/package.json index d44985b..e759fed 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,8 @@ { "name": "simple-starter-pack", - "version": "1.1.0", - "description": "Simple HTML5 + (S)CSS + JS starter pack (boilerplate) with pre-configured usefull tools & libraries", - "main": "src/function.js", + "version": "2.0.0", + "description": "Simple HTML5 + (S)CSS + TypeScript starter pack (boilerplate) with pre-configured usefull tools & libraries", + "main": "src/js/app.ts", "scripts": { "postinstall": "gulp build" }, @@ -25,15 +25,13 @@ "kit", "starter-kit", "live reload", - "html5" + "html5", + "typescript" ], "devDependencies": { - "@babel/core": "^7.13.8", - "@babel/preset-env": "^7.13.9", "browser-sync": "^2.26.14", "gulp": "^4.0.2", "gulp-autoprefixer": "^8.0.0", - "gulp-babel": "^8.0.0", "gulp-if": "^3.0.0", "gulp-imagemin": "^7.1.0", "gulp-load-plugins": "^2.0.6", @@ -46,11 +44,17 @@ "include-media": "^1.4.9", "jsdom-quokka-plugin": "^1.0.16", "mdcolorize": "^1.0.1", + "node-notifier": "^10.0.1", "normalize.css": "^8.0.1", "path": "^0.12.7", + "webpack-stream": "^7.0.0", "yargs": "^17.3.1" }, "dependencies": { - "sass": "^1.46.0" + "@types/jquery": "^3.5.14", + "sass": "^1.54.5", + "ts-loader": "^9.2.8", + "typescript": "^4.8.2", + "webpack": "^5.74.0" } } diff --git a/dist/.keepgit b/src/js/app.ts similarity index 100% rename from dist/.keepgit rename to src/js/app.ts diff --git a/src/js/function.js b/src/js/function.js deleted file mode 100644 index e69de29..0000000 diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..751f585 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "outDir": "./dist/", + "noImplicitAny": true, + "module": "es6", + "target": "es5", + "jsx": "react", + "allowJs": true, + "moduleResolution": "node" + }, + "include": ["src/js/*"], + "exclude": ["node_modules"] +} \ No newline at end of file