使用webpack打包ThinkPHP的资源文件

使用webpack打包ThinkPHP的资源文件

利用本身的空余时间一直在维护http://www.wx2share.com这个小网站,全是一我的在弄,因为只租得起虚拟空间,因此后台采用了简单方便的ThinkPHP反正主要也是作一些CURD操做ThinkPHP仍是挺好用的,帮我提早作好了好多功能。
本人并不擅长前端,可是开始开发这个小网站发现,基本的功能所有要经过前端javascript来实现。一开始的时候全部的javascript代码所有写在html页面里。也没有太大问题,后来为了页面性能要求把全部javascript和css所有minify一下。我采用的办法把js和css经过资源文件引入。而后用在线的minify工具复制过去minify之后,复制回来保存为xxx.min.js。方法是笨一点,可是一来页面很少,到也没有多麻烦。可是渐渐的页面开始多了之后,就愈来愈不方便了。javascript

原来方法中的痛点

  • 每次minify都要复制来复制去,文件多了麻烦
  • 代码重复利用率不高。php

    • 办法1:重复代码所有复制到新文件(傻)
    • 办法2:公用代码保存为单独文件分别引入,不利入页面性能

这时候让我不得不考虑使用前端自动化构键工具css

构键工具的选择

我对工具的要求不高,一开始纯粹主是我了minify js和css因此一开始我选用了gulp,由于用过因此直接就用了html

gulp的方案

打包第三方的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始乱终弃了。

webpack的方案

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了,能够说至关的方便了

尚未解决的问题

  • 居然没有办法仅仅把代码contact在一块儿的办法,个人vendor文件仍是用gulp生成的,还好这个文件基本上不怎么修改。我过经过定义
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缓存问题,我给每一个资源文件加了一个时间戳,每次都要手动去改一下好麻烦 但愿你们能提供好的方法来帮我解决这两个问题。

相关文章
相关标签/搜索