利用本身的空餘時間一直在維護http://www.wx2share.com這個小網站,全是一我的在弄,因爲只租得起虛擬空間,因此後臺採用了簡單方便的ThinkPHP反正主要也是作一些CURD操做ThinkPHP仍是挺好用的,幫我提早作好了好多功能。
本人並不擅長前端,可是開始開發這個小網站發現,基本的功能所有要經過前端javascript來實現。一開始的時候全部的javascript代碼所有寫在html頁面裏。也沒有太大問題,後來爲了頁面性能要求把全部javascript和css所有minify一下。我採用的辦法把js和css經過資源文件引入。而後用在線的minify工具複製過去minify之後,複製回來保存爲xxx.min.js。方法是笨一點,可是一來頁面很少,到也沒有多麻煩。可是漸漸的頁面開始多了之後,就愈來愈不方便了。javascript
代碼重複利用率不高。php
- 辦法1:重複代碼所有複製到新文件(傻)
- 辦法2:公用代碼保存爲單獨文件分別引入,不利入頁面性能
這時候讓我不得不考慮使用前端自動化構鍵工具css
我對工具的要求不高,一開始純粹主是我了minify js和css因此一開始我選用了gulp,由於用過因此直接就用了html
打包第三方的javascript類庫前端
gulp.task('vendor',()=> gulp.src([ 'bower_components/jquery/dist/jquery.js', 'bower_components/bootstrap/dist/js/bootstrap.js', 'src/lib/bootstrap-modal.js', 'src/lib/bootstrap-modalmanager.js', 'bower_components/jquery.cycle2/index.js' ]).pipe(concat('vendor.js')) .pipe(gulpif(production,uglify({ mangle:true }))) .pipe(gulp.dest('Public/Home/js')) );
不錯,完美。只要 NODE_ENV=production 時還能自動壓縮和混淆jsjava
minify css並拷貝圖片Public對應目錄。node
gulp.task('styles',()=> gulp.src('src/css/show.css') .pipe(plumber()) .pipe(autoprefixer()) .pipe(gulpif(production,cssmin())) .pipe(gulp.dest('Public/Home/css')) ); gulp.task('img',()=> gulp.src('src/img/*') .pipe(gulp.dest('Public/Home/img')) ); gulp.task('watchcss',()=> gulp.watch('src/css/**/*.css',['styles']) );
也很不錯,經過gulp.watch還實現CSS實時更新。jquery
打包本身的js文件webpack
gulp.task('browserify', () =>{ var bundler = browserify({ //entries:['src/js/pcshowpage.js'], entries:['src/js/pcshowpage/index.js'], standalone:'pcshowpage', cache:{}, packageCache:{}, plugin:[] }) bundler.transform(babelify,{ presets: ["es2015"]}); bundler.bundle() .pipe(source('pcshowpage.js')) .pipe(buffer()) .pipe(sourcemaps.init({loadMaps: true})) .pipe(gulpif(production, streamify(uglify({ mangle: true })))) .pipe(sourcemaps.write('./')) .pipe(gulp.dest('Public/Home/js'))} );
至關以及徹底的完美,經過babel的轉譯還能愉快的用ES6來寫代碼了,什麼新特性都能用來了。代碼也能模塊化了。不一樣的功能寫成不一樣的模塊,只要import 一下就能夠用了。gulp經過browserify幫你轉譯成瀏覽器能識別的ES5寫起代碼來很是愉快。
經過watchify也能實現代碼的實時更新web
gulp.task('browserify-watch', () =>{ //var bundler = watchify(browserify('src/js/pcshowpage.js', watchify.args)); var bundler = browserify({ //entries:['src/js/pcshowpage.js'], entries:['src/js/pcshowpage/index.js'], standalone:'pcshowpage', cache:{}, packageCache:{}, plugin:[watchify] }) bundler.transform(babelify,{ presets: ["es2015"]}); bundler.on('update', rebundle); return rebundle(); function rebundle() { var start = Date.now(); bundler.bundle() .on('error', function(err) { gutil.log(gutil.colors.red(err.toString())); }) .on('end', function() { gutil.log(gutil.colors.green('Finished rebundling in', (Date.now() - start) + 'ms.')); }) .pipe(source('pcshowpage.js')) .pipe(buffer()) .pipe(sourcemaps.init({loadMaps: true})) .pipe(sourcemaps.write('./')) .pipe(gulp.dest('Public/Home/js')); } });
看起來很是的美好了,愉快的寫完了這個頁面開始重構別一個頁面的時候,問題來了,我不會用gulp定義多個出口文件,(就是我不會,沒用過而已,gulp確定能作到的)我也知道用代碼來定義多個bundler確定是作到,可是我滿腦子就想到了webpack定義多個出口文件是多麼方便。因此我就對gulp始亂終棄了。
entry: { css:"./src/css/index.js", mainpage:"./src/js/mainpage/index.js", pcshowpage: "./src/js/pcshowpage/index.js", combpage:"./src/js/combpage/index.js", tbkpage:"./src/js/tbkpage/index.js", }, output: { library: '[name]', libraryTarget: "umd", path: path.resolve(__dirname, PublicPath), filename: 'js/[name].js' }
就這麼簡單明瞭,每一個js文件生成了單獨的輸出文件。不一樣的頁面引入不一樣的js就行了。接下來經過CommonsChunkPlugin抽取公用的模塊到common.js,
new webpack.optimize.CommonsChunkPlugin({ name: "common", minChunks : 2, chunks:["mainpage","pcshowpage","combpage","tbkpage"] }),
這樣一些幾個頁面通用的代碼都被抽到common.js中了。其它圖片,CSS, Font等內容所有由不一樣的loader來處理,看起來比gulp明瞭多了。
在目錄下,新建一個dev.js
require('shelljs/global') var merge = require('webpack-merge') var path = require('path') var webpack = require('webpack') var webpackConfig = require('./webpack.config') var devcoifng=merge(webpackConfig, { devtool: '#eval-source-map', //能夠理解爲繼承通用配置,在dev模式下生成source map 方便調試。 }) var c=webpack(devcoifng); c.watch({ // watch options: aggregateTimeout: 300, // wait so long for more changes poll: true // use polling instead of native watchers // pass a number to set the polling interval }, function(err, stats) { if (err) throw err process.stdout.write(stats.toString({ colors: true, modules: false, children: false, chunks: false, chunkModules: false }) + '\n') });
運行 node dev.js
經過wath()實現了,代碼的實時更新。修改完js代碼一保存,資源目錄下的文件就能夠更新,刷新一下頁面就能夠載入最新的代碼了。debug的時候因爲有source map 就能夠看清究竟是哪裏的代碼有問題,還支持單步調試。
因爲生成環境還須要配置的東西更多,因此我新建了一個prod.conf.js
var webpack = require('webpack') var merge = require('webpack-merge') var baseWebpackConfig = require('./webpack.config') module.exports = merge(baseWebpackConfig, { plugins: [ new webpack.DefinePlugin({ 'process.env': { NODE_ENV: 'production' } }), new webpack.optimize.UglifyJsPlugin({ //壓縮混淆代碼 compress: { warnings: false } }), new webpack.optimize.OccurenceOrderPlugin(), // extract css into its own file ] })
再建一個build.js
require('shelljs/global') env.NODE_ENV = 'production' var path = require('path') var webpack = require('webpack') var webpackConfig = require('./webpack.prod.conf') webpack(webpackConfig, function (err, stats) { if (err) throw err process.stdout.write(stats.toString({ colors: true, modules: false, children: false, chunks: false, chunkModules: false }) + '\n') })
只要運行 node build.js
就能夠生成已經壓縮混淆好的js和css了,能夠說至關的方便了
var dependencies = [ './bower_components/jquery/dist/jquery.js', './bower_components/bootstrap/dist/js/bootstrap.js', './src/lib/bootstrap-modal.js', './src/lib/bootstrap-modalmanager.js', './bower_components/jquery.cycle2/index.js' ] ........ //而後在 entry 加入 entry:{ vendor:dependencies ........ ....... } //再配置一個 new webpack.optimize.CommonsChunkPlugin({ name: "vendor", minChunks : Infinity, }), .....
這樣生成的vendor文件裏面全部的類庫全變成AMD JS 規範了再頁面中引入沒有辦法正常使用jquery等類庫,gulp contact的作法就是簡單把幾個文件合併在一塊兒而已,在頁面中引入不影響使用,
還有一個問題是CDN引發的問題。
因爲個人html模版頁面仍是本身寫的,並且沒有用webpack處理,由於我用了thinkphp的模版功能,頁面的header footer 我定義在base.html中,其它頁面繼承一下,這樣,好多重複代碼就不用寫了。可是也沒有辦法用html-webpack-plugin來處理了,爲了解決CDN緩存問題,我給每一個資源文件加了一個時間戳,每次都要手動去改一下好麻煩 但願你們能提供好的方法來幫我解決這兩個問題。