11"use strict" ;
22
3- const gulp = require ( 'gulp-help' ) ( require ( 'gulp' ) ) ;
3+ const gulp = require ( 'gulp' ) ;
44const bower = require ( 'gulp-bower' ) ;
55const purify = require ( 'gulp-purifycss' ) ;
66const concatCss = require ( 'gulp-concat-css' ) ;
@@ -9,17 +9,17 @@ const gulpIgnore = require('gulp-ignore');
99const htmlreplace = require ( 'gulp-html-replace' ) ;
1010const gulpRemoveHtml = require ( 'gulp-remove-html' ) ;
1111const htmlmin = require ( 'gulp-html-minifier' ) ;
12- const gulpAmpValidator = require ( 'gulp-amphtml-validator' ) ;
1312const replace = require ( 'gulp-replace' ) ;
14- const uncss = require ( 'gulp-uncss' ) ;
13+ const { exec } = require ( 'child_process' ) ; // ✅ 用於 AMP 驗證
14+ const fs = require ( 'fs' ) ;
1515
1616const paths = {
1717 src : {
18- dir : './resources/public/weekly' ,
18+ dir : './resources/public/weekly' ,
1919 html : './resources/public/weekly/**/*.html'
2020 } ,
2121 dist : {
22- dir : './build/dist' ,
22+ dir : './build/dist' ,
2323 html : './build/dist/**/*.html'
2424 } ,
2525 tmp : {
@@ -28,24 +28,26 @@ const paths = {
2828 }
2929} ;
3030
31- gulp . task ( 'bower' , function ( ) {
31+ // --- Tasks ---
32+
33+ gulp . task ( 'bower' , function ( ) {
3234 return bower ( ) ;
3335} ) ;
3436
35- gulp . task ( 'compile:css' , [ 'bower' ] , function ( ) {
36- return gulp . src ( [ './bower_components/bootstrap/dist/css/bootstrap.min.css' ,
37- './resources/public/weekly/css/screen.css' ] )
37+ gulp . task ( 'compile:css' , gulp . series ( 'bower' , function ( ) {
38+ return gulp . src ( [
39+ './bower_components/bootstrap/dist/css/bootstrap.min.css' ,
40+ './resources/public/weekly/css/screen.css'
41+ ] )
3842 . pipe ( concatCss ( 'app.css' ) )
3943 . pipe ( purify ( [ paths . src . html ] ) )
40- // remove !importent which not supported by amphtml
44+ // remove unsupported AMP syntax
4145 . pipe ( replace ( / ! i m p o r t a n t / g, '' ) )
42- // remove @-ms-viewport which not supported by amphtml
4346 . pipe ( replace ( / @ - m s - v i e w p o r t \s * { \n ( .* ?) \n } / g, '' ) )
4447 . pipe ( gulp . dest ( paths . tmp . dir ) ) ;
45- } ) ;
48+ } ) ) ;
4649
47- // inline-css inserts the cleaned + minified CSS into HTML
48- gulp . task ( 'build:inline-css' , [ 'compile:css' ] , function ( ) {
50+ gulp . task ( 'build:inline-css' , gulp . series ( 'compile:css' , function ( ) {
4951 return gulp . src ( paths . src . html )
5052 . pipe ( htmlreplace ( {
5153 'cssInline' : {
@@ -54,57 +56,58 @@ gulp.task('build:inline-css', ['compile:css'], function() {
5456 }
5557 } ) )
5658 . pipe ( gulp . dest ( paths . dist . dir ) ) ;
57- } ) ;
59+ } ) ) ;
5860
59- gulp . task ( 'build:remove-html' , [ 'build:inline-css' ] , function ( ) {
61+ gulp . task ( 'build:remove-html' , gulp . series ( 'build:inline-css' , function ( ) {
6062 return gulp . src ( paths . dist . html )
61- . pipe ( gulpRemoveHtml ( {
62- 'keyword' : 'build:removeHtml'
63- } ) )
63+ . pipe ( gulpRemoveHtml ( { keyword : 'build:removeHtml' } ) )
6464 . pipe ( gulp . dest ( paths . dist . dir ) ) ;
65- } ) ;
65+ } ) ) ;
6666
67- gulp . task ( 'build:minify-html' , [ 'build:remove-html' ] , function ( ) {
67+ gulp . task ( 'build:minify-html' , gulp . series ( 'build:remove-html' , function ( ) {
6868 return gulp . src ( paths . dist . html )
69- . pipe ( htmlmin ( { collapseWhitespace : true ,
70- minifyJS : true ,
71- minifyCSS : true ,
72- removeComments : true } ) )
69+ . pipe ( htmlmin ( {
70+ collapseWhitespace : true ,
71+ minifyJS : true ,
72+ minifyCSS : true ,
73+ removeComments : true
74+ } ) )
7375 . pipe ( gulp . dest ( paths . dist . dir ) ) ;
74- } ) ;
76+ } ) ) ;
7577
76- gulp . task ( 'build:fix-html-link' , [ 'build:minify-html' ] , function ( ) {
78+ gulp . task ( 'build:fix-html-link' , gulp . series ( 'build:minify-html' , function ( ) {
7779 return gulp . src ( paths . dist . html )
78- // make all link create new tab
7980 . pipe ( replace ( / < a \s + h r e f = " h t t p / g, '<a target="_blank" href="http' ) )
8081 . pipe ( gulp . dest ( paths . dist . dir ) ) ;
81- } ) ;
82+ } ) ) ;
8283
84+ // ✅ New AMP Validation Task using official CLI
85+ gulp . task ( 'validate:amphtml' , gulp . series ( 'build:minify-html' , function ( done ) {
86+ console . log ( '🔍 Running AMP validation...' ) ;
87+
88+ exec ( `npx amphtml-validator ${ paths . dist . html } ` , ( err , stdout , stderr ) => {
89+ if ( stdout ) console . log ( stdout ) ;
90+ if ( stderr ) console . error ( stderr ) ;
91+
92+ if ( err ) {
93+ console . error ( '❌ AMP validation failed.' ) ;
94+ done ( new Error ( 'AMP validation failed.' ) ) ;
95+ } else {
96+ console . log ( '✅ AMP validation passed.' ) ;
97+ done ( ) ;
98+ }
99+ } ) ;
100+ } ) ) ;
83101
84- gulp . task ( 'validate:amphtml' , [ 'build:minify-html' ] , function ( ) {
85- return gulp . src ( paths . dist . html )
86- // Some page no need to support amp, just ignore it
87- . pipe ( gulpIgnore . exclude ( [ '**/404.html' ] ) )
88- // Valide the input and attach the validation result to the "amp" property
89- // of the file object.
90- . pipe ( gulpAmpValidator . validate ( ) )
91- // Print the validation results to the console.
92- . pipe ( gulpAmpValidator . format ( ) )
93- // Exit the process with error code (1) if an AMP validation error
94- // occurred.
95- . pipe ( gulpAmpValidator . failAfterError ( ) ) ;
96- } ) ;
97-
98- gulp . task ( 'build' , 'build all resources' , [
102+ // --- Build sequence ---
103+ gulp . task ( 'build' , gulp . series (
99104 'bower' ,
100105 'compile:css' ,
101106 'build:inline-css' ,
102107 'build:remove-html' ,
103108 'build:minify-html' ,
104109 'build:fix-html-link' ,
105110 'validate:amphtml'
106- ] ) ;
111+ ) ) ;
107112
108- gulp . task ( 'default' , 'build all resources' , [
109- 'build' ,
110- ] ) ;
113+ gulp . task ( 'default' , gulp . series ( 'build' ) ) ;
0 commit comments