使用webpack打包ThinkPHP的资源文件

利用自己的空余时间一直在维护http://www.wx2share.com这个小网站,全是一个人在弄,由于只租得起虚拟空间,所以后台采用了简单方便的ThinkPHP反正主要也是做一些CURD操作ThinkPHP还是挺好用的,帮我提前做好了好多功能。

本人并不擅长前端,但是开始开发这个小网站发现,基本的功能全部要通过前端javascript来实现。一开始的时候所有的javascript代码全部写在html页面里。也没有太大问题,后来为了页面性能要求把所有javascript和css全部minify一下。我采用的办法把js和css通过资源文件引入。然后用在线的minify工具复制过去minify以后,复制回来保存为xxx.min.js。方法是笨一点,但是一来页面不多,到也没有多麻烦。但是渐渐的页面开始多了以后,就越来越不方便了。

原来方法中的痛点

  • 每次minify都要复制来复制去,文件多了麻烦
  • 代码重复利用率不高。
  • 办法1:重复代码全部复制到新文件(傻)
  • 办法2:公用代码保存为单独文件分别引入,不利入页面性能

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

构键工具的选择

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

gulp的方案

打包第三方的javascript类库

  1. gulp.task('vendor',()=>
  2. gulp.src([
  3. 'bower_components/jquery/dist/jquery.js',
  4. 'bower_components/bootstrap/dist/js/bootstrap.js',
  5. 'src/lib/bootstrap-modal.js',
  6. 'src/lib/bootstrap-modalmanager.js',
  7. 'bower_components/jquery.cycle2/index.js'
  8. ]).pipe(concat('vendor.js'))
  9. .pipe(gulpif(production,uglify({ mangle:true })))
  10. .pipe(gulp.dest('Public/Home/js'))
  11. );

不错,完美。只要 NODE_ENV=production 时还能自动压缩和混淆js

minify css并拷贝图片Public对应目录。

  1. gulp.task('styles',()=>
  2. gulp.src('src/css/show.css')
  3. .pipe(plumber())
  4. .pipe(autoprefixer())
  5. .pipe(gulpif(production,cssmin()))
  6. .pipe(gulp.dest('Public/Home/css'))
  7. );
  8. gulp.task('img',()=>
  9. gulp.src('src/img/*')
  10. .pipe(gulp.dest('Public/Home/img'))
  11. );
  12. gulp.task('watchcss',()=>
  13. gulp.watch('src/css/**/*.css',['styles'])
  14. );

也很不错,通过gulp.watch还实现CSS实时更新。

打包自己的js文件

  1. gulp.task('browserify', () =>{
  2. var bundler = browserify({
  3. //entries:['src/js/pcshowpage.js'],
  4. entries:['src/js/pcshowpage/index.js'],
  5. standalone:'pcshowpage',
  6. cache:{},
  7. packageCache:{},
  8. plugin:[]
  9. })
  10. bundler.transform(babelify,{ presets: ["es2015"]});
  11. bundler.bundle()
  12. .pipe(source('pcshowpage.js'))
  13. .pipe(buffer())
  14. .pipe(sourcemaps.init({loadMaps: true}))
  15. .pipe(gulpif(production, streamify(uglify({ mangle: true }))))
  16. .pipe(sourcemaps.write('./'))
  17. .pipe(gulp.dest('Public/Home/js'))}
  18. );

相当以及完全的完美,通过babel的转译还能愉快的用ES6来写代码了,什么新特性都能用来了。代码也能模块化了。不同的功能写成不同的模块,只要import 一下就可以用了。gulp通过browserify帮你转译成浏览器能识别的ES5写起代码来非常愉快。

通过watchify也能实现代码的实时更新

  1. gulp.task('browserify-watch', () =>{
  2. //var bundler = watchify(browserify('src/js/pcshowpage.js', watchify.args));
  3. var bundler = browserify({
  4. //entries:['src/js/pcshowpage.js'],
  5. entries:['src/js/pcshowpage/index.js'],
  6. standalone:'pcshowpage',
  7. cache:{},
  8. packageCache:{},
  9. plugin:[watchify]
  10. })
  11. bundler.transform(babelify,{ presets: ["es2015"]});
  12. bundler.on('update', rebundle);
  13. return rebundle();
  14. function rebundle() {
  15. var start = Date.now();
  16. bundler.bundle()
  17. .on('error', function(err) {
  18. gutil.log(gutil.colors.red(err.toString()));
  19. })
  20. .on('end', function() {
  21. gutil.log(gutil.colors.green('Finished rebundling in', (Date.now() - start) + 'ms.'));
  22. })
  23. .pipe(source('pcshowpage.js'))
  24. .pipe(buffer())
  25. .pipe(sourcemaps.init({loadMaps: true}))
  26. .pipe(sourcemaps.write('./'))
  27. .pipe(gulp.dest('Public/Home/js'));
  28. }
  29. });

看起来非常的美好了,愉快的写完了这个页面开始重构别一个页面的时候,问题来了,我不会用gulp定义多个出口文件,(就是我不会,没用过而已,gulp肯定能做到的)我也知道用代码来定义多个bundler肯定是做到,但是我满脑子就想到了webpack定义多个出口文件是多么方便。所以我就对gulp始乱终弃了。

webpack的方案

  1. entry: {
  2. css:"./src/css/index.js",
  3. mainpage:"./src/js/mainpage/index.js",
  4. pcshowpage: "./src/js/pcshowpage/index.js",
  5. combpage:"./src/js/combpage/index.js",
  6. tbkpage:"./src/js/tbkpage/index.js",
  7. },
  8. output: {
  9. library: '[name]',
  10. libraryTarget: "umd",
  11. path: path.resolve(__dirname, PublicPath),
  12. filename: 'js/[name].js'
  13. }

就这么简单明了,每个js文件生成了单独的输出文件。不同的页面引入不同的js就好了。接下来通过CommonsChunkPlugin抽取公用的模块到common.js,

  1. new webpack.optimize.CommonsChunkPlugin({
  2. name: "common",
  3. minChunks : 2,
  4. chunks:["mainpage","pcshowpage","combpage","tbkpage"]
  5. }),

这样一些几个页面通用的代码都被抽到common.js中了。其它图片,CSS, Font等内容全部由不同的loader来处理,看起来比gulp明了多了。

开发与产生环境不同生成的配置。

开发环境

在目录下,新建一个dev.js

  1. require('shelljs/global')
  2. var merge = require('webpack-merge')
  3. var path = require('path')
  4. var webpack = require('webpack')
  5. var webpackConfig = require('./webpack.config')
  6. var devcoifng=merge(webpackConfig, {
  7. devtool: '#eval-source-map', //可以理解为继承通用配置,在dev模式下生成source map 方便调试。
  8. })
  9. var c=webpack(devcoifng);
  10. c.watch({ // watch options:
  11. aggregateTimeout: 300, // wait so long for more changes
  12. poll: true // use polling instead of native watchers
  13. // pass a number to set the polling interval
  14. }, function(err, stats) {
  15. if (err) throw err
  16. process.stdout.write(stats.toString({
  17. colors: true,
  18. modules: false,
  19. children: false,
  20. chunks: false,
  21. chunkModules: false
  22. }) + '\n')
  23. });

运行 node dev.js

通过wath()实现了,代码的实时更新。修改完js代码一保存,资源目录下的文件就可以更新,刷新一下页面就可以载入最新的代码了。debug的时候由于有source map 就可以看清到底是哪里的代码有问题,还支持单步调试。

生成环境

由于生成环境还需要配置的东西更多,所以我新建了一个prod.conf.js

  1. var webpack = require('webpack')
  2. var merge = require('webpack-merge')
  3. var baseWebpackConfig = require('./webpack.config')
  4. module.exports = merge(baseWebpackConfig, {
  5. plugins: [
  6. new webpack.DefinePlugin({
  7. 'process.env': {
  8. NODE_ENV: 'production'
  9. }
  10. }),
  11. new webpack.optimize.UglifyJsPlugin({ //压缩混淆代码
  12. compress: {
  13. warnings: false
  14. }
  15. }),
  16. new webpack.optimize.OccurenceOrderPlugin(),
  17. // extract css into its own file
  18. ]
  19. })

再建一个build.js

  1. require('shelljs/global')
  2. env.NODE_ENV = 'production'
  3. var path = require('path')
  4. var webpack = require('webpack')
  5. var webpackConfig = require('./webpack.prod.conf')
  6. webpack(webpackConfig, function (err, stats) {
  7. if (err) throw err
  8. process.stdout.write(stats.toString({
  9. colors: true,
  10. modules: false,
  11. children: false,
  12. chunks: false,
  13. chunkModules: false
  14. }) + '\n')
  15. })

只要运行 node build.js

就可以生成已经压缩混淆好的js和css了,可以说相当的方便了

还没有解决的问题

  • 竟然没有办法仅仅把代码contact在一起的办法,我的vendor文件还是用gulp生成的,还好这个文件基本上不怎么修改。我过通过定义
  1. var dependencies = [
  2. './bower_components/jquery/dist/jquery.js',
  3. './bower_components/bootstrap/dist/js/bootstrap.js',
  4. './src/lib/bootstrap-modal.js',
  5. './src/lib/bootstrap-modalmanager.js',
  6. './bower_components/jquery.cycle2/index.js'
  7. ]
  8. ........
  9. //然后在 entry 加入
  10. entry:{
  11. vendor:dependencies
  12. ........
  13. .......
  14. }
  15. //再配置一个
  16. new webpack.optimize.CommonsChunkPlugin({
  17. name: "vendor",
  18. minChunks : Infinity,
  19. }),
  20. .....

这样生成的vendor文件里面所有的类库全变成AMD JS 规范了再页面中引入没有办法正常使用jquery等类库,gulp contact的做法就是简单把几个文件合并在一起而已,在页面中引入不影响使用,

  • 还有一个问题是CDN引起的问题。

由于我的html模版页面还是自己写的,而且没有用webpack处理,因为我用了thinkphp的模版功能,页面的header footer 我定义在base.html中,其它页面继承一下,这样,好多重复代码就不用写了。但是也没有办法用html-webpack-plugin来处理了,为了解决CDN缓存问题,我给每个资源文件加了一个时间戳,每次都要手动去改一下好麻烦

希望大家能提供好的方法来帮我解决这两个问题。

使用webpack打包ThinkPHP的资源文件的更多相关文章

  1. Pyinstaller打包: 将资源文件或文件夹打包到最后生成的exe中

    前提:用pyinstaller打包时部分资源文件可以利用qrc转成py文件来读取,但是有部分文件类型不适用. 原理:Pyinstaller 将资源文件一起打包到exe中.当exe运行时,会生成一个临时 ...

  2. vue2.0 配置build项目打包目录、资源文件(assets\static)打包目录

    vue项目默认的打包路径:根目录下的dist文件夹下: 但是在项目开发中,我们肯定希望项目提交到svn目录或者git目录下,否则每次复制过去,太麻烦了: 那怎么配置打包路径呢?下面来看看: 我们找到打 ...

  3. angular4.0 配置打包路径以及资源文件404问题

    一.配置打包路径 配置打包路径,便于提交到SVN,不用每次都复制粘贴 在.angular-cli.json文件中修改"outDir"的路径,打包后的项目将发布到路径下 二.解决打包 ...

  4. maven打包额外的资源文件

    在用Maven打包的时候发现,有一些资源文件打包不到jar包中,于是了解了一下Maven的打包配置,最后得到了解决问题的办法. Maven资源文件的默认约定 构建Maven项目的时候,如果没有进行特殊 ...

  5. 关于使用maven打包如何聚合资源文件

    多数情况下,我们使用maven管理多个子工程,在最后maven打包阶段将多个子工程聚合到一个jar或war包.单个子工程会有自己独立的资源配置文件,在打包的时候我们需要将其聚合在一起(各子工程中的配置 ...

  6. webpack打包多个入口文件

    打包后的目录结构: webpack.config.js // path 模块提供了一些用于处理文件路径 const path = require('path'); // fs模块用于对系统文件及目录进 ...

  7. vue项目通过webpack打包生成的dist文件放到express环境里运行(vue+webpack+express)

    1.首先需要的原料肯定是vue打包生成的dist文件 在vue项目目录下运行:npm run build,等待运行结束,会在项目目录下生成一个dist文件夹,里面会生成一些文件(如下图示) 小的项目文 ...

  8. webpack打包指定HTML的文件并引入指定的chunks

    1. 安装 html-webpack-plugin npm install html-webpack-plugin --save-dev 2. 在webpack.config.js中配置 const ...

  9. webpack打包优化并开启gzip

    应用场景:项目使用webpack2.x进行打包,打包后静态资源通过nginx转发配置: 问题:webpack打包后的资源文件特别,特别大,没打包之前页面一个页面js有2M左右(其中已经抽离了css)? ...

随机推荐

  1. hdu 5720

    考虑三个树枝:a,b,c若c是将要抛出的树枝,那么形成三角形的条件是a+b>c and a-b<c 可以写成 c属于开区间(a-b,a+b)对于每个C和许许多多的其他边,如何保证C不构成三 ...

  2. 字符串匹配的Boyer-Moore算法

    作者: 阮一峰    http://www.ruanyifeng.com/blog/2013/05/boyer-moore_string_search_algorithm.html 上一篇文章,我介绍 ...

  3. caffe在windows 下的配置及matlab接口编译(无GPU)

    本人机子windows 10,matlab2015a,vs2013(官网使用的是vs2013) 1.首先去github上下载caffe的windows包,地址:https://github.com/B ...

  4. vc编译 curl 7.36.0

    CURL邮件列表中提到官方最新版本的windows devel包中缺少文件,而我又用不到https,所以我就自己下载源码包来编译了 下载源码包:http://curl.haxx.se/download ...

  5. 从一个简单例子来理解js引用类型指针的工作方式

    <script> var a = {n:1}; var b = a; a.x = a = {n:2}; console.log(a.x);// --> undefined conso ...

  6. var与this,{}与function 小记

    JavaScript var是用来定义一个变量,this常用来定义或调用一个属性或方法.但是在全局范围内,this和var定义变量是等价的. window console.log('window:', ...

  7. Programming Entity Framework CodeFirst--表关系约定

    表之间的关系分为一对多,多对多,一对一三种,实质就是对外键进行配置. 一.一对多 1. Required Destination包含Lodging>的集合. public class Desti ...

  8. C#反射基础知识和实战应用

    首先来说一下什么是反射? 反射提供了封装程序集.模块和类型的对象(Type类型) 可以使用反射动态的创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型,然后,可以调用类型的方法或访问其字段和 ...

  9. [蓝牙] 6、基于nRF51822的蓝牙心率计工程消息流Log分析(详细)

    开机初始化Log Log编号 函数名   所在文件名 000001: main ..\main.c 000002: timers_init ..\main.c 000003: gpiote_init ...

  10. Linux C/C++的编译

    以前在Linux上面编译过C,但是没有编译过C++,今天用到了,就稍微学习了一下. 简单的介绍 linux 中最重要的编译工具是 GCC.GCC 是 GNU 的 C 和 C++ 编译器.实际上,GCC ...