Webpack&React (二) Webpack现状

齐乐
2023-12-01

在GitHub上发现的学习webpack和react的很好的文章,原文链接

  从Webpack的方展史上来看,它是强大的.早些时候对脚本文件的处理还只是压缩和合并,但随着时代的发展,现在怎样部署我们的JavaScript代码已经是一个繁杂的工作了.

SPAs(单页面应用)

  这个问题随着单页面应用(SPAs)的不断发展而升级,往往这样的应用需要依靠许多重量级的库,最后作为产品时需要把它们一次性的加载到页面中,而Webpack在许多时候都是一个不错的解决安案.

  使用npm,现在是很流行的,它是Node.js的包管理工具,有丰富的资源.并且随着前端的发展,npm逐步成熟了起来,并使用它来管理我们工程的依赖.

构建工具和打包

  从历史上讲,有许多构建系统,如GruntGulp,它们现在也还是一个不错的选择,并且可以通过npm来安装它们.

  当我们需要拼接各种资源并且打包产品时,这时构建工具是一个好帮手,它允许我们跨平台的执行操作,我们有打包工具,如Browserify或者Webpack.

  更进一步的,JSPM推进包管理可以直接在浏览器中.它依赖于System.js,一个动态的模块加载库. JSPM不像BrowserifyWebpack,我们可以在开发过程中完全不关心最后要怎么打包,把这个任务由它来完成.

Make

  历史悠久的构建工具. 比我还要老.

Grunt

  在Gulp之前Grunt是主力,它的插件体系很受欢迎,但你可能会不得不保持300行的配置文件.下面是一个示例:

module.exports = function(grunt) {
  grunt.initConfig({
    jshint: {
      files: ['Gruntfile.js', 'src/**/*.js', 'test/**/*.js'],
      options: {
        globals: {
          jQuery: true
        }
      }
    },
    watch: {
      files: ['<%= jshint.files %>'],
      tasks: ['jshint']
    }
  });

  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-watch');

  grunt.registerTask('default', ['jshint']);
};

  在上面的例子里我们定义了两个基本任务, jshint是一个检查你JavaScript代码中可能出现的问题点的工具,还有一个watch任务,时实监视我们代码的改动.

  实际中,我们将有各种类型的任务,如工程构建,例子显示了怎样构建,它很强大,但是却隐藏了太多细节,让我们很难理解到底发生了什么.

  grunt-webpack插件可以让我们在Grunt环境中件使用Webpack.

Gulp

  Gulp采取了不同的方式,写配置时,不是靠每个插件单独配置.Gulp构建在管道概念之上.如果你熟悉 Unix,这一点上是相同的. 包含了.sources, filters, 和sinks.

  sources对应于文件,filters执行操作(例如转换JavaScript),最终,结果将传递给sinks(例如,我们的构建目录),下面是一段Gulpfile

var gulp = require('gulp');
var coffee = require('gulp-coffee');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var sourcemaps = require('gulp-sourcemaps');
var del = require('del');

var paths = {
    scripts: ['client/js/**/*.coffee', '!client/external/**/*.coffee']
};

// Not all tasks need to use streams
// A gulpfile is just another node program and you can use all packages available on npm
gulp.task('clean', function(cb) {
  // You can use multiple globbing patterns as you would with `gulp.src`
  del(['build'], cb);
});

gulp.task('scripts', ['clean'], function() {
  // Minify and copy all JavaScript (except vendor scripts)
  // with sourcemaps all the way down
  return gulp.src(paths.scripts)
    .pipe(sourcemaps.init())
      .pipe(coffee())
      .pipe(uglify())
      .pipe(concat('all.min.js'))
    .pipe(sourcemaps.write())
    .pipe(gulp.dest('build/js'));
});

// Rerun the task when a file changes
gulp.task('watch', function() {
  gulp.watch(paths.scripts, ['scripts']);
});

// The default task (called when you run `gulp` from CLI)
gulp.task('default', ['watch', 'scripts']);

  配置文件是JS代码写的,你可以hack它,你可以用现有的Node.js包作为Gulp的插件,诸如此类.相比Grunt,你对任务的流转会有一个清晰的概念,最终我们会为各种任务写大量样板代码.

  gulp-webpack插件可以让我们在Gulp环境中件使用Webpack.

Browserify

  使用JavaScript处理模块一直有些问题,这个语言本身并没有模块的概念直到ES6的出现,因此,我们提出了各种解决方案,例如AMD.

实践中,它只服务于CommonJS(Node.js 格式), 优点是,你经常可以hook到npm, 避免重造轮子.

Browserify是一个模块问题解决方案, 它提供给我们打包CommonJS模块到一起的方法, 你可以在hook它对于Gulp.

Browserify 生态系统是由很多小的模块组成。这种方式,Browserify 坚持 Unix 哲学。Browserify 比 Webpack容易一点,是一个不错的选择.

Webpack

  你可以说Webpack是Browserify的一个整体的解决方案, Browserify是由许多小工具组成的, 而Webpack提供了大量的开箱即用的核心功能,可以使用指定的loadersplugins进行扩展。

Webpack将会通过require语句来遍历你的工程,生成定义的包,你甚至可以动态的载入你自已的依赖使用require.ensure语句, 这个加载机制对于CSS和@import是友好支持的.也有处理如压缩,本地化,热加载等插件。

例如,require('style!css!./main.css')加载这个main.css通过CSS和style从内到外的顺序. 下面是一个示例:

webpack.config.js

var webpack = require('webpack');

module.exports = {
  entry: './entry.js',
  output: {
    path: __dirname,
    filename: 'bundle.js'
  },
  module: {
    loaders: [
      {
        test: /\.css$/,
        loaders: ['style', 'css']
      }
    ]
  },
  plugins: [
    new webpack.optimize.UglifyJsPlugin()
  ]
};

这个配置模式可能让Webpack有点儿不透明,很难理解它作了什么,在更富杂的情况下尤其如此. 作者有相关的书可以学习.

JSPM

对比早期的工作它是完全不同的,它有一个小的CLI工具,用于安装新包和发布打包等. 它支持SystemJS插件,使我们可以加载各种格式到工程中.

JSPM还很年轻,可能会有些问题,但是觉对不容小觑.

为什么使用Webpack?

Webpack可以处理打包构建的问题,但选择它是因为它支持模块的热插拔,接下来将说如何设置它.

模块热插拔(HMR)

你可以有相似的工具如 LiveReload 或者Browsersync , 这些工具会在你改变代码时自动刷新你的浏览器, HMR则做到了更进一步,在React中,它允许应用管理自已的状态, 这听起来很简单,但在实际中有很大的区别.

包拆分

抛开HMR. Webpack的打包能力是广范的,它允许你用另种方式拆分包,你甚至可以在程序持行时动态的加载.这种延时加载对于大型应用非常好用,你可以在你需要它时加载它们.

资源Hash

使用Webpack,可以方便的注于一个hash值到每个打包文件的名字 (例如,app.d587bbd6e38337f5accd.js).允许我们更改一个包.包拆分后当发生改变时,客户端只重新加载发生改变的这部分数据即可.

 Loaders 和 Plugins

这些小的功能加起来,我们可以方便的干很多事情,Webpack有一定的学习曲线,但即便始此,它仍是一个好的工具,特别是在以后会为我们节省许多保贵的时间.

支持的模块格式

  • CommonJS
  • ES6
  • AMD
  • UMD
 类似资料: