React with Webpack
目录结构
-ProjectName
|-----------build
|-----------src
|--------a.html, b.html, ...
|--------javascripts
|--------main.js
|--------components
|-----ComponentA
|----css(A.css, xx.css)
|----A.jsx
|-----ComponentB
- http://facebook.github.io/react/ tutorial
- https://fakefish.github.io/react-webpack-cookbook/Optimizing-rebundling.html
-
当项目越发复杂的时候,这样的方法会变得越来越有效。你可以把所有复杂的操作隐藏在 scripts 里面来保证界面的简洁。
-
不过潜在的问题是这种方法会导致如果你使用一些特殊的指令的时候只能在 Unix 环境中使用。所以如果你需要考虑一些未知的环境中的话,那么 gulp-webpack 会是一个好的解决方案。
webpack-dev-server - 在 localhost:8080 建立一个 Web 服务器 --devtool eval - 为你的代码创建源地址。当有任何报错的时候可以让你更加精确地定位到文件和行号 --progress - 显示合并代码进度 --colors - Yay,命令行中显示颜色! --content-base build - 指向设置的输出目录
Webpack 允许你使用不同的模块类型,但是 “底层”必须使用同一种实现。所有的模块可以直接在盒外运行。
相对路径是相对当前目录。绝对路径是相对入口文件,这个案例中是 main.js。
你不需要去特意去使用 .js,但是如果你引入之后高亮会更好。你可能有一些 .js 文件和一些 .jsx 文件,甚至一些图片和 css 可以用 Webpack 引入,甚至可以直接引入 node_modules 里的代码和特殊文件。
记住,Webpack 只是一个模块合并!也就是说你可以设置他去加载任何你写的匹配,只要有一个加载器。
在开发环境中,最理想的是编译最多 200 到 800 毫秒的速度,取决于你在开发的应用。 为了不让 Webpack 去遍历 React JS 及其依赖,你可以在开发中重写它的行为。
在一个大项目中和很多开发者一起工作的时候,类型检查对你的项目来讲是保证了稳定性,就像一个很好的测试做的事情。所以使用 Flow 当然不是必要条件。对于那些需要和很多开发者一起做大项目的开发者来说类型检测是一种非常寻常的事。 Webpack 引入 Flow 之后会非常方便。
可以为每个组件把所有你的 CSS 加载到入口主文件中来做任何事情. 可以选择你所需要的方式, 加载特定的CSS到组件中。 加载 CSS 需要 css-loader 和 style-loader,他们做两件不同的事情,css-loader会遍历 CSS 文件,然后找到 url() 表达式然后处理他们,style-loader 会把原来的 CSS 代码插入页面中的一个 style 标签中。 也可以在 CommonJS 和 AMD 中做同样的事情。
根据你的应用,你可能会考略三种策略。另外,你需要考虑把一些基础的 CSS 内联到初始容器中(index.html),这样设置的结构能够在应用下载和执行的时候加载剩下的应用。
如果你想发挥应用中多重入口文件的优势,你可以在每个入口点包含各自的 CSS:你把你的模块用文件夹分离,每个文件夹有各自的 CSS 和 JavaScript 文件。再次,当应用发布的时候,导入的 CSS 已经加载到每个入口文件中。
你可以根据这个策略为每个组件创建 CSS 文件,可以让组件名和 CSS 中的 class 使用一个命名空间,来避免一个组件中的一些 class 干扰到另外一些组件的 class。
.MyComponent-wrapper {
background-color: #EEE;
}
当 Webpack-dev-server 在 浏览器自动刷新 下运行的时候,CSS 也会自动更新,不过有点不同的是,当你改变了一个 CSS 文件,属于那个文件的标签会更新新的内容但不会刷新。
在 “React Native” 中你不再需要使用任何 CSS 文件,你只需要使用 style 属性,可以把你的 CSS 定义成一个对象,那样就可以根据你的项目重新来考略你的 CSS 策略。
import React from 'react';
var style = {
backgroundColor: '#EEE'
};
export default React.createClass({
render: function () {
return (
<div style={style}>
<h1>Hello world</h1>
</div>
)
}
});
如果你想使用编译 CSS,这里有两种可用的加载器:less-loader 和 sass-loader
直到 HTTP/2 你才能在应用加载的时候避免设置太多 HTTP 请求。根据浏览器不同你必须设置你的并行请求数,如果你在你的 CSS 中加载了太多图片的话,可以自动把这些图片转成 BASE64 字符串然后内联到 CSS 里来降低必要的请求数,这个方法取决与你的图片大小。你需要为你的应用平衡下载的大小和下载的数量,不过 Webpack 可以让这个平衡十分轻松适应。
字体实在是非常难引入正确,首先,通常我们有 4 种不一样的格式,但是只有其中一种会被对应的浏览器使用到。你肯定不会想引入全部四种格式,这样只会让 CSS 文件更加膨胀,然后又没办法优化。
如果不考略 Opera Mini,所有的浏览器都支持 .woff 和 .svg 格式。问题是不同格式下在各种浏览器下字体看起来会有一点点不同。所以测试 .woff 和 .svg,然后找出能够在所有浏览器中看起来最好的那个。
生产配置
- 配置你的 package.json 里的脚本
- 创建一个生产的配置
合并成单文件:
- 应用很小
- 很少会更新应用
- 你不太关心初始加载时间
当你的应用依赖其他库尤其是像 React JS 这种大型库的时候,你需要考虑把这些依赖分离出去,这样就能够让用户在你更新应用之后不需要再次下载第三方文件。当满足下面几个情况的时候你就需要这么做了:
- 当你的第三方的体积达到整个应用的 20% 或者更高的时候
- 更新应用的时候只会更新很小的一部分
- 你没有那么关注初始加载时间,不过关注优化那些回访用户在你更新应用之后的体验
- 有手机用户
你的应用可能有多个路径, 就是应用中有两个或者多个 URL 相应不同的页面,这里就是提供这样的解决方案
- 你的应用有多种不同的用户体验,但是他们共享了很多代码。
- 你有一个使用更少组件的手机版本
- 你的应用是典型的权限控制,你不想为普通用户加载所有管理用户的代码。
Webpack 也可以实现懒加载入口文件,意味着应用的一部分只在需要的时候加载,一个典型的例子是用户只有访问一些应用特定的部分
-
你有一个相对比较大的应用,可以让用户可以访问应用的不同部分
-
你非常关注初始渲染时间
openProfile() { require.ensure([], () => { var Profile = require('./Profile.js'); this.setState({ currentComponent: Profile }); }); }
第一个数组参数是什么?:如果你尝试去懒加载一段由另一个懒加载的代码加载的代码的话,把它作为依赖写在数组里,就把路径写进去,比如 ['./FunnyButton.js']
isomorphic
客户端:
var React = require('react');
var AppState = require('./client/AppState.js');
var App = require('./App.js');
React.render(<App state={AppState}/>, document.body);
服务端:
var React = require('react');
var App = require('./App.js');
var AppState = require('./server/AppState.js');
var index = '<!DOCTYPE html><html><head></head><body>{{component}}</body></html>';
app.get('/', function (req, res) {
var componentHtml = React.renderToString(App({state: AppState}));
var html = index.replace('{{component}}', componentHtml);
res.type('html');
res.send(html);
});