ES6推出已經有幾個年頭了,平時也有學過一些基本語法,無奈實踐經驗太少。而且前端早已脫離了刀耕火種的時代,一些自動化構建工具像gulp、webpack等也需要熟練掌握。最近剛簽了三方,閑暇之余就找了個ES6實戰視頻系統學習了一下,然而,由於視頻中用到的打包工具和編譯工具版本不同,導致在按照視頻進行項目構建時遇到了很多坑。在此寫篇文章記錄一下,邊學習邊填坑,希望幫助到一些人吧。
項目名稱:ES6 彩票項目實戰
項目搭建環境:win10 任務自動化工具(gulp)后端(nodejs express框架)node版本:v10.5.0 npm版本:6.1.0 命令行工具:Cmder
github: https://github.com/bestchenyan/lotteryTicket
視頻就不公布了,感興趣的請私信~
1 ES6項目構建
1.1 基礎架構
1.2 任務自動化(gulp)
什么是任務自動化?
只關心頁面如何寫如何與后端交互,至於ES6怎么轉換成ES5或ES3、頁面變化后怎么進行自動刷新、怎么進行文件合並等都不需要關心。配置好自動化構建工具,輸入一行命令即可。
什么是gulp?gulp的作用
參考官網:https://gulpjs.com/
1.3 編譯工具(babel)
什么是babel ?
babel 是js的編譯器,有的瀏覽器不支持es6需要用babel編譯成ES5或ES3。
1.4 代碼實現
1.4.1 創建一個ES6前端工程
1、先創建一個根目錄結構
(1)app:頁面目錄(我們后面主要在這里寫頁面)。包括js、css、views,views里面的ejs是express的模板文件,可以把它當成html看待。
(2)server:服務目錄(配置后端服務目錄)。express框架搭建的后台服務器
(3)tasks:構建目錄(構建工具配置目錄)。gulp的相關任務配置。
2、切換到server文件夾下安裝nodejs的express框架
step1、安裝nodejs:參見:https://www.cnblogs.com/bestchenyan/p/9298237.html MAC系統自行搜索配置
step2、全局安裝express框架
npm install -g express
npm install -g express-generator
在server文件夾下執行
express -e .
完成后執行:npm install 安裝相關包!
安裝完成后,你的server文件夾是這樣的:
3、切換到構建目錄tasks,配置構建工具。
在tasks下創建util文件夾,在util文件夾下創建args.js文件。
4、切換到根目錄下,目前我們的文件目錄如下
在項目中是要從npm中安裝很多包的,我們在項目根目錄中需要一個package.json的文件。可以手動創建,但是有了npm,就用npm命令來創建,根目錄下執行:
npm init
這是交互性的命令,你可以一直按回車鍵就行。最后輸入yes 回車 搞定!你的根目錄就會有一個package.json的包,從npm下載的依賴包都會放在這里。
5、根目錄下,創建設置babel編譯工具配置文件,文件名如下:只能是這個名字,先不寫內容,后面寫
.babelrc
6、根目錄下,創建gulp配置文件。官網說的是創建gulpfile.js文件,但是這里我們用這個文件名:
gulpfile.babel.js
因為我們接下來寫的腳本都是用的ES6的語法,如果不這么命名,執行gulp腳本時會報錯。
7、最終的項目目錄
項目目錄已經完成,開始配置task(構建目錄)下的各種文件,以及搭建服務器
1.4.2 自動構建配置、服務器搭建
1、在tasks/util/args.js腳本中編寫如下代碼
關於yargs的用法,請參考:https://www.npmjs.com/package/yargs

1 var yargs = require('yargs'); 2 const args = yargs 3 // 區分是線上還是開發環境,默認false 開發環境 4 .option('production', { 5 boolean: true, 6 default: false, 7 describe: 'min all script' 8 }) 9 // 是否監聽 修改的文件 我改了 js、css是否需要自動編譯 10 .option('watch', { 11 boolean: true, 12 default: false, 13 describe: 'watch all files' 14 }) 15 // 是否詳細輸出日志 16 .option('verbose', { 17 boolean: true, 18 default: false, 19 describe: 'log' 20 }) 21 // 強制生成sourcemaps 22 .option('sourcemaps', { 23 describe: 'force the creation of sourcemaps' 24 }) 25 // 服務器端口 26 .option('port', { 27 string: true, 28 default: 8080, 29 describe: 'server port' 30 }) 31 .argv
2、在tasks 文件夾下新建scripts.js文件,配置如下:

1 var gulp = require('gulp'); 2 var gulpif = require('gulp-if'); 3 var concat = require('gulp-concat'); 4 var webpack = require('webpack'); 5 var webpackStream = require('webpack-stream'); 6 var named = require('vinyl-named'); 7 var livereload = require('gulp-livereload'); 8 var plumber = require('gulp-plumber'); 9 var rename = require('gulp-rename'); 10 var uglify = require('gulp-uglify'); 11 var { log, colors } = require('gulp-util'); 12 var args = require('./util/args'); 13 14 gulp.task('scripts', () => { 15 // 文件打開 16 return gulp.src(['app/js/index.js']) 17 // 錯誤處理 18 .pipe(plumber({ 19 errorHandle: function() { 20 21 } 22 })) 23 // 文件名標識 24 .pipe(named()) 25 // webpack打包編譯 26 .pipe(webpackStream({ 27 module: { 28 rules: [{ 29 test: /\.m?js$/, 30 exclude: /(node_modules|bower_components)/, 31 use: { 32 loader: 'babel-loader', 33 } 34 }] 35 } 36 }), null, (err, stats) => { 37 log(`Finished '${colors.cyan('scripts')}'`, stats.toString({ 38 chunks: false 39 })) 40 }) 41 // 編譯輸出路徑 42 .pipe(gulp.dest('server/public/js')) 43 // 輸出cp一份 重命名 44 .pipe(rename({ 45 basename: 'cp', 46 extname: '.min.js' 47 })) 48 // 壓縮 49 .pipe(uglify({ compress: { properties: false }, output: { 'quote_keys': true } })) 50 // 壓縮之后生成路徑 51 .pipe(gulp.dest('server/public/js')) 52 // 監聽文件 文件變化后自動刷新 53 .pipe(gulpif(args.watch, livereload())) 54 55 })
注意:babel版本已經更新了,但是中文官網並沒有更新。請訪問英文官網:https://babeljs.io/
此外,webpack目前是4.X版本了,新的配置方法參考:https://github.com/babel/babel-loader
3、安裝script.js中導入的包
在根目錄下執行:
npm install gulp gulp-if gulp-concat webpack webpack-stream vinyl-named gulp-livereload gulp-plumber gulp-rename gulp-uglify gulp-util yargs --save-dev
4、這是自動安裝的,安裝完的package.json如下
5、在tasks文件夾下創建處理模版的構建腳本pages.js

var gulp = require('gulp'); var gulpif = require('gulp-if'); var livereload = require('gulp-livereload'); var args = require('./util/args'); gulp.task('pages',()=>{ return gulp.src('app/**/*.ejs') .pipe(gulp.dest('server')) .pipe(gulpif(args.watch,livereload())) })
6、在tasks文件夾下創建處理CSS的構建腳本css.js

1 var gulp = require('gulp'); 2 var gulpif = require('gulp-if'); 3 var livereload = require('gulp-livereload'); 4 var args = require('./util/args'); 5 gulp.task('css',()=>{ 6 return gulp.src('app/**/*.css') 7 .pipe(gulp.dest('server/public')) 8 .pipe(gulpif(args.watch,livereload())) 9 })
7、在tasks文件夾下創建處理服務器的構建腳本server.js

1 var gulp = require('gulp'); 2 var gulpif = require('gulp-if'); 3 var liveserver = require('gulp-live-server'); 4 var args = require('./util/args'); 5 gulp.task('serve',(cb)=>{ 6 // if(!args.watch) return cb();//這里跟視頻中不一樣,要注釋掉才能跑服務 7 var server = liveserver.new(['--harmony','server/bin/www']); 8 server.start(); 9 10 gulp.watch(['server/public/**/*.js','server/views/**/*.ejs'],function(file){ 11 server.notify.apply(server,[file]); 12 }); 13 gulp.watch(['server/routes/**/*.js','server/app.js'],function(){ 14 server.start.bind(server)() 15 }); 16 })
在這個文件中引入了gulp-live-server的包,同樣在根目錄下進行安裝:
npm install gulp-live-server --save-dev
要想讓所有的任務自動完成,還差一個環節。app是原始的項目目錄,但是服務器處理的是server/public下的文件。源文件發生改變時,怎么樣自動編譯生成到到public文件下呢?所以還需要一個browser.js文件。
9、在tasks文件夾下創建瀏覽器監聽相關文件browser.js

1 var gulp = require('gulp'); 2 var gulpif = require('gulp-if'); 3 var gutil = require('gulp-util'); 4 var args = require('./util/args'); 5 6 gulp.task('browser',(cb)=>{ 7 // if (!args.watch) return cb();//這里好像不影響,以防萬一我也注釋了 8 gulp.watch('app/**/*.js',['scripts']); 9 gulp.watch('app/**/*.ejs',['pages']); 10 gulp.watch('app/**/*.css',['css']); 11 });
10、在tasks文件夾下創建清空制定文件clean.js

1 var gulp = require('gulp'); 2 var del = require('del'); 3 var args = require('./util/args'); 4 gulp.task('clean',()=>{ 5 return del(['server/public','server/views']) 6 })
這里引入了del包,所以需要安裝一下,命令如下:
npm install del --save-dev
11、在tasks文件夾下創建build.js,把所有任務關聯起來

1 var gulp = require('gulp'); 2 var gulpSequence = require('gulp-sequence'); 3 gulp.task('bulid',gulpSequence('clean','css','pages','scripts',['browser','serve']));
這里引入了gulp-sequence包,所以需要安裝一下,命令如下:
npm install gulp-sequence --save-dev
12、在tasks文件夾下創建default.js

1 var gulp = require('gulp'); 2 gulp.task('default',['bulid']);
13、安裝babel包
在srcipts.js中的webpack部分使用了babel-loader包,需要安裝一下。另外由於babel升級了, 還需要額外安裝一下 @babel/core
npm install @babel/core babel-loader --save-dev
安裝 @babel/preset-env
npm install @babel/preset-env --save-dev
這一部分都是按照babel官網配置的:https://babeljs.io/setup#installation
14、配置.babelrc 文件,參考官網
{
"presets": ["@babel/preset-env"]
}
15、配置gulpfile.babel.js文件

1 var requireDir =require('require-dir'); 2 requireDir('./tasks');
同樣,安裝require-dir包:
npm install require-dir --save-dev
完事兒了,文件有點多。具體每個文件的作用,詳見視頻~~~~
最后的最后坑!!!最后的最后坑!!!最后的最后坑!!!
打開server文件夾下的app.js文件,添加一行代碼。如下圖:
app.use(require('connect-livereload')());
一定要添加,要不然服務跑不起來。
同樣,要安裝connect-livereload包
npm install connect-livereload --save-dev
1.4.3 測試
1、在根目錄下運行命令:gulp --watch
圖中錯誤可以忽略,強迫症患者可以把gulp的版本降到3.9.0,如果你在全局也安裝了gulp也一並降到3.9.0
看到這個界面說明你已經配置成功了,在瀏覽器中輸入:localhost:3000
很好,沒有報錯。頁面內容是空白的。因為我們還沒寫html文件。在app/views/index.ejs文件下編寫html代碼
保存代碼,刷新頁面,服務可以用了。
2、編譯ES6代碼
在app/views/index.ejs中導入入口文件app/js/index.js
其中,導入的index.js是入口文件,里面放的是es6代碼:
重點坑!!! 重點坑!!! 重點坑!!!
這里會報錯,錯誤代碼如下:LiveReload disabled because it could not find its own <SCRIPT> tag
解決方案:在app/views/index.ejs中添加如下代碼
<script src="http://localhost:35729/livereload.js?snipver=1" async="" defer=""></script>
一定要添加在index.js下面,要不然不起作用!
解決方案出處:https://github.com/AveVlad/gulp-connect/issues/254
然后,不要刷新瀏覽器!不要刷新瀏覽器!不要刷新瀏覽器!你會看到:
爽吧,你只需要在app下寫頁面就行了,gulp會自動打包 壓縮 編譯。最后放上我的package.json,把各個模塊的版本給大家看下。如遇版本更迭請大家自行去官網查找配置方案。
沒有了。大家也可以自行采坑,這樣有助於學習!我也是初學者,有什么問題歡迎交流。