Webpack 和 React 小书

Webpack 和 React 小书

全文地址
Gitbook 英文原版javascript

这本小书的目的是引导你进入 React 和 Webpack 的世界。他们两个都是很是有用的技术,若是同时使用他们,前端开发会更加有趣。css

这本小书会提供全部相关的技能。若是你只是对 React 感兴趣,那能够跳过 Webpack 相关的内容,反之亦然。 若是想学习更多的相关知识能够移步 SurviveJS - Webpack and Reacthtml

React

React 是一个可以让开发模块变成简单的库。一旦你理解他的工做原理,那你就能够用它搭建本身的程序,这是不一样相似 Angular 那种试着包揽一切的框架不一样的地方。前端

若是你想很快过一遍 React 的知识点,那么 React 官方教程 是一个很好的开始。java

可能 React 最有趣的事是它一直会尝试调整传统的 web 组件的思路。它让咱们从新思考关注点的分离。它(React Native)也会影响 App 开发。 React Native 提供了一种使用 Javascript 开发原生应用同时保证了原生性能。node

Webpack

Webpack 很是容易操做,它是一个模块合并的工具,本质就是一个可以把各类组件(HTML,CSS,JS)构建成项目。最方便的是你只须要初始化配置一次,Webpack 会替你作那些繁琐的事情,同时也保证了让你能够在项目中混合使用各类技术而不头疼。react

若是你在 Webpack 方面彻底是新手的,但想开始一个简单的教程的话,能够去 Pete Hunt's guide。你能够在那里学习到一些基础的使用,这里只是那边的一个补充。webpack

介绍 Webpack

在 Web 开发历程上,咱们构建了不少小型的技术解决方案,好比用 HTML 去描述页面结构,CSS 去描述页面样式,Javascript 去描述页面逻辑,或者你也能够用一些好比 Jade 去取代 HTML,用 Sass 或 Less 去取代CSS,用 CoffeeScript 或者 TypeScript 之类的去取代 Javascript,不过项目中的依赖多是一件比较烦恼的事情。(须要安装额外不少的库)git

这里有不少为何咱们须要尝试那些新技术的理由。无论咱们用什么,总之,咱们仍是但愿使用那些可以处理在浏览器端的方案,因此出来了编译方案。历史上已经有不少分享了,好比 Make 多是不少解决方案中最知名且是可行的方案。GruntGulp 是在是前端的世界中最流行的解决方案,他们两个都有不少很是有用的插件。NPM(Node.js 的包管理器)则包含了他们两个。github

Grunt

Grunt 是相比后面几个更早的项目,他依赖于各类插件的配置。这是一个很好的解决方案,可是请相信我,你不会想看到一个 300 行的 Gruntfile。若是你好奇 Grunt 的配置会如何,那么这里是有个从 Grunt 文档 的例子:

javascriptmodule.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']);

};

Gulp

Gulp 提供了一个不同的解决方案,而不是依赖于各类插件的配置。Gulp 使用了一个文件流的概念。若是你熟悉 Unix,那么 Gulp 对你来讲会差很少,Gulp 会提供你一些简单化的操做。在这个解决方案中,是去匹配一些文件而后操做(就是说和 JavaScript 相反)而后输出结果(好比输出在你设置的编译路径等)。这里有一个简单的 Gulpfile 的例子:

javascriptvar 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'],
};

// 不是全部的任务须要使用 streams
// 一个 gulpfile 只是另外一个node的程序,因此你可使用全部 npm 的包
gulp.task('clean', function(cb) {
  // 你能够用 `gulp.src` 来使用多重通配符模式
  del(['build'], cb);
});

gulp.task('scripts', ['clean'], function() {
  // 压缩和复制全部 JavaScript (除了第三方库)
  // 加上 sourcemaps
  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'));
});

// 监听文件修改
gulp.task('watch', function() {
  gulp.watch(paths.scripts, ['scripts']);
});

// 默认任务(就是你在命令行输入 `gulp` 时运行)
gulp.task('default', ['watch', 'scripts']);

这些配置都是代码,因此当你遇到问题也能够修改,你也可使用已经存在的 Gulp 插件,可是你仍是须要写一堆模板任务。

Browserify

处理 Javascript 模块一直是一个大问题,由于这个语言在 ES6 以前没有这方面的概念。所以咱们仍是停留在90年代,各类解决方案,好比提出了 AMD。在实践中只使用 CommonJS ( Node.js 所采用的格式)会比较有帮助,而让工具去处理剩下的事情。它的优点是你能够发布到 NPM 上来避免从新发明轮子。

Browserify 解决了这个问题,它提供了一种能够把模块集合到一块儿的方式。你能够用 Gulp 调用它,此外有不少转换小工具可让你更兼容的使用(好比 watchify 提供了一个文件监视器帮助你在开发过程当中更加自动化地把文件合并起来),这样会省下不少精力。毋庸置疑,必定程度来说,这是一个很好的解决方案。

Webpack

Webpack 扩展了 CommonJs 的 require 的想法,好比你想在 CoffeeScript、Sass、Markdown 或者其余什么代码中 require 你想要的任何代码的话?那么 Webpack 正是作这方面的工做。它会经过配置来取出代码中的依赖,而后把他们经过加载器把代码兼容地输出到静态资源中。这里是一个 Webpack 官网 上的例子:

javascriptmodule.exports = {
    entry: "./entry.js",
    output: {
        path: __dirname,
        filename: "bundle.js"
    },
    module: {
        loaders: [
            { test: /\.css$/, loader: "style!css" }
        ]
    }
};

在接下来的章节中咱们会使用 Webpack 来构建项目来展现它的能力。你能够用其余工具和 Webpack 一块儿使用。它不会解决全部事情,只是解决一个打包的难题,不管如何,这是在开发过程当中须要解决的问题。

踏上征途

在开始以前,你须要把你的 Node.js 和 NPM 都更新到最新的版本。访问 nodejs.org 查看安装详情。咱们将会使用 NPM 安装一些工具。

开始使用 Webpack 很是简单,我会展现给你看使用它的一个简单的项目。第一步,为你的项目新建一个文件夹,而后输入 npm init,而后填写相关问题。这样会为你建立了 package.json,不用担忧填错,你能够以后修改它。

安装 Webpack

接下来咱们安装 Webpack,咱们要把它安装在本地,而后把它做为项目依赖保存下来。这样你能够在任何地方编译(服务端编译之类的)。输入 npm i wepack --save-dev。若是你想运行它,就输入 node_modules/.bin/webpack

目录结构

项目的目录结构长这样:

  • /app

    • main.js
    • component.js
  • /build

    • bundle.js (自动建立)
    • index.html
  • package.json
  • webpack.config.js

咱们会使用 Webpack 在咱们的 /app 里来自动建立 bundle.js 。接下来,咱们来设置 webpack.config.js

设置 Webpack

Webpack 的配置文件长这样:

webpack.config.js

javascriptvar path = require('path');


module.exports = {
    entry: path.resolve(__dirname, 'app/main.js'),
    output: {
        path: path.resolve(__dirname, 'build'),
        filename: 'bundle.js',
    },
};

运行你的第一个编译

如今咱们有了一个最简单的配置,咱们须要有什么东西去编译,让咱们开始一个经典的 Hello World,设置 /app 像这样:

app/component.js

javascript'use strict';


module.exports = function () {
    var element = document.createElement('h1');

    element.innerHTML = 'Hello world';

    return element;
};

app/main.js

javascript'use strict';
var component = require('./component.js');


document.body.appendChild(component());

如今在你的命令行运行 webpack,而后你的应用会开始编译,一个 bundle.js 文件就这样出如今你的 /build 文件夹下,须要在 build/ 下的 index.html 去启动项目。

build/index.html

html<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8"/>
  </head>
  <body>
    <script src="bundle.js"></script>
  </body>
</html>

这个文件能够用 html-webpack-plugin 来生成。若是你以为冒险,那就把剩下的工具交给它来作。使用它就只有一个配置的问题。通常来讲使用 Webpack 来工做就是这么个套路。

运行应用

只要双击 index.html 或者设置一个 Web 服务指向 build/ 文件夹。

设置 package.json scripts

npm 是一个很是好用的用来编译的指令,经过 npm 你能够不用去担忧项目中使用了什么技术,你只要调用这个指令就能够了,只要你在 package.json 中设置 scripts 的值就能够了。

在这个案例中咱们把编译步骤放到 npm run build 中是这样:

  1. npm i webpack --save - 若是你想要把 Webpack 做为一个项目的开发依赖,就可使用 --save-dev,这样就很是方便地让你在开发一个库的时候,不会依赖工具(但不是个好方法!)。
  2. 把下面的内容添加到 package.json中。
json"scripts": {
    "build": "webpack"
  }

如今你能够输入 npm run build 就能够编译了。

当项目愈加复杂的时候,这样的方法会变得愈来愈有效。你能够把全部复杂的操做隐藏在 scripts 里面来保证界面的简洁。

不过潜在的问题是这种方法会致使若是你使用一些特殊的指令的时候只能在 Unix 环境中使用。因此若是你须要考虑一些未知的环境中的话,那么 gulp-webpack 会是一个好的解决方案。

注意 NPM 会找到 Webpack,npm run 会把他临时加到 PATH来让咱们这个神奇的命令工做。

工做流

若是须要一直输入 npm run build 确实是一件很是无聊的事情,幸运的是,咱们能够把让他安静的运行,让咱们设置 webpack-dev-server

设置 webpack-dev-server

第一步,输入 npm i webpack-dev-server --save,此外,咱们须要去调整 package.json scripts 部分去包含这个指令,下面是基本的设置:

package.json

json{
  "scripts": {
    "build": "webpack",
    "dev": "webpack-dev-server --devtool eval --progress --colors --hot --content-base build"
  }
}

当你在命令行里运行 npm run dev 的时候他会执行 dev 属性里的值。这是这些指令的意思:

  1. webpack-dev-server - 在 localhost:8080 创建一个 Web 服务器
  2. --devtool eval - 为你的代码建立源地址。当有任何报错的时候可让你更加精确地定位到文件和行号
  3. --progress - 显示合并代码进度
  4. --colors - Yay,命令行中显示颜色!
  5. --content-base build - 指向设置的输出目录

总的来讲,当你运行 npm run dev 的时候,会启动一个 Web 服务器,而后监听文件修改,而后自动从新合并你的代码。真的很是简洁!

访问 http://localhost:8080 你会看到效果。

浏览器自动刷新

当运行 webpack-dev-server 的时候,它会监听你的文件修改。当项目从新合并以后,会通知浏览器刷新。为了可以触发这样的行为,你须要把你的 index.html 放到 build/ 文件夹下,而后作这样的修改:

build/index.html

html<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8"/>
  </head>
  <body>
    <script src="http://localhost:8080/webpack-dev-server.js"></script>
    <script src="bundle.js"></script>
  </body>
</html>

咱们须要增长一个脚本当发生改动的时候去自动刷新应用,你须要在配置中增长一个入口点。

javascriptvar path = require('path');


module.exports = {
    entry: ['webpack/hot/dev-server', path.resolve(__dirname, 'app/main.js')],
    output: {
        path: path.resolve(__dirname, 'build'),
        filename: 'bundle.js',
    },
};

就是这样!如今你的应用就能够在文件修改以后自动刷新了。

默认环境

在上面的例子中咱们建立了 index.html 文件来获取更多的自由和控制。一样也能够从 http://localhost:8080/webpack-dev-server/bundle 运行应用。这会触发一个默认的你不能控制的 index.html ,它一样会触发一个容许iFrame中显示重合并的过程。

引入文件

模块

Webpack 容许你使用不一样的模块类型,可是 “底层”必须使用同一种实现。全部的模块能够直接在盒外运行。

ES6 模块

javascriptimport MyModule from './MyModule.js';

CommonJS

javascriptvar MyModule = require('./MyModule.js');

AMD

javascriptdefine(['./MyModule.js'], function (MyModule) {

});

理解文件路径

一个模块须要用它的文件路径来加载,看一下下面的这个结构:

  • /app

    • /modules
    • MyModule.js
    • main.js (entry point)
    • utils.js

打开 main.js 而后能够经过下面两种方式引入 app/modules/MyModule.js

app/main.js

javascript// ES6
import MyModule from './modules/MyModule.js';

// CommonJS
var MyModule = require('./modules/MyModule.js');

最开始的 ./ 是 “相对当前文件路径”

让咱们打开 MyModule.js 而后引入 app/utils

app/modules/MyModule.js

javascript// ES6 相对路径
import utils from './../utils.js';

// ES6 绝对路径
import utils from '/utils.js';

// CommonJS 相对路径
var utils = require('./../utils.js');

// CommonJS 绝对路径
var utils = require('/utils.js');

相对路径是相对当前目录。绝对路径是相对入口文件,这个案例中是 main.js

我须要使用文件后缀么?

不,你不须要去特地去使用 .js,可是若是你引入以后高亮会更好。你可能有一些 .js 文件和一些 .jsx 文件,甚至一些图片和 css 能够用 Webpack 引入,甚至能够直接引入 node_modules 里的代码和特殊文件。

记住,Webpack 只是一个模块合并!也就是说你能够设置他去加载任何你写的匹配,只要有一个加载器。咱们稍后会继续深刻这个话题。

剩下全文地址:
全文地址

相关文章
相关标签/搜索