browserify和webpack使用笔记 - trigkit4
由于是笔记,没有做过多内容上的整理,贴出来仅供参考
Browserify
Browserify
可以让你使用类似于 node
的 require()
的方式来组织浏览器端的 Javascript
代码。
Browserify
本身也是一个NodeJS模块,通过npm安装。
浏览器没有定义require
方法,但是Node.js
有。用Browserify
你可以用require
以在Node中同样的方法来写代码
module.exports
新建一名为main.js
,黏贴如下代码:
module.exports = function (n,m) { return n*m;};
在新建一名为test.js
的文件:
var foo = require('./main');console.log(foo(5,10));
然后终端输入:node test
=>输出50
你可以使用module.exports
导出任何你想输出的类型值。
module.exports
相当于exports
,但你不能使用exports = function(){}
的形式.
API
使用实例:
var browserify = require('browserify');var b = browserify();b.add('./browser/main.js');b.bundle().pipe(process.stdout);
b.add(file,opts)
从file
添加一个入口文件,当捆绑的包被加载时会执行该文件。
b.require(file,opts)
从外部加载文件(require(file)
)
b.bundle(cb)
捆绑文件和他们的依赖使其成为一个单一的js文件。
b.external(file)
简单的说,Grunt / Gulp
和 browserify / webpack
不是一回事。
1)Gulp / Grunt
可以理解为帮助前端自动化的工具,用于优化前端工作流程。比如自动刷新页面、combo、压缩css、js、编译less等等。二者的区别可以自行百度,个人推荐Gulp。
2)browserify / webpack
提供的是一个前端模块化的方案,和requirejs类似但又有不同。
requirejs
是一种在线"编译" 模块的方案,相当于在页面上加载一个AMD 解释器,以便于览器能够识别 define、exports、module,而这些东西就是用于模块化的关键。
而browserify / webpack
,则是一个预编译模块的方案。它是预编译的,不需要在浏览器中加载解释器。
因此完全可以gulp+webpack
或者gulp+browserify
这样的方式搭配使用。
webpack
CommonJS
服务器端的 Node.js
遵循 CommonJS
规范,该规范的核心思想是允许模块通过 require 方法来同步
加载所要依赖的其他模块,然后通过 exports
或 module.exports
来导出需要暴露的接口。
require("module");require("../file.js");exports.doStuff = function() {};module.exports = someValue;
AMD
Asynchronous Module Definition 规范其实只有一个主要接口 define(id?, dependencies?, factory)
,它要在声明模块的时候指定所有的依赖 dependencies
,并且还要当做形参传到 factory
中,对于依赖的模块提前执行,依赖前置。
define("module", ["dep1", "dep2"], function(d1, d2) { return someExportedValue;});require(["module", "../file"], function(module, file) { /* ... */ });
优点:
适合在浏览器环境中异步加载模块
可以并行加载多个模块
CMD
Common Module Definition
规范和 AMD 很相似,尽量保持简单,并与 CommonJS
和 Node.js
的
Modules 规范保持了很大的兼容性。
define(function(require, exports, module) { var $ = require('jquery'); var Spinning = require('./spinning'); exports.doSomething = ... module.exports = ...})
优点:
依赖就近,延迟执行
可以很容易在 Node.js 中运行
对于全局安装的webpack,直接执行此命令会默认使用当前目录的webpack.config.js
作为配置文件。
通常我们会将 Webpack
安装到项目的依赖中,这样就可以使用项目本地版本的 Webpack
。
# 进入项目目录# 确定已经有 package.json,没有就通过 npm init 创建# 安装 webpack 依赖$ npm install webpack --save-dev//生成如下的代码 "devDependencies": { "webpack": "^1.12.9" }
entry参数
定义了打包后的入口文件,可以是数组(所有文件打包生成一个filename
文件),对象或者字符串
{ entry: { page1: "./page1", page2: ["./entry1", "./entry2"] }, output: { // Make sure to use [name] or [id] in output.filename // when using multiple entry points filename: "[name].bundle.js", path: "dist/js/page", chunkFilename: "[id].bundle.js" }}
该段代码最终会生成一个 page1.bundle.js
和 page2.bundle.js
,并存放到 ./dist/js/page
文件夹下
output
参数是个对象,定义了输出文件的位置及名字:
path
: 打包文件存放的绝对路径 publicPath
: 网站运行时的访问路径 filename
:打包后的文件名
Webpack 本身只能处理 JavaScript 模块,如果要处理其他类型的文件,就需要使用 loader
进行转换。
不同模块的加载是通过模块加载器(webpack-loader)来统一管理的。Loader 可以理解为是模块和资源的转换器,它本身是一个函数,接受源文件作为参数,返回转换的结果。
module: { //加载器配置 loaders: [//.css 文件使用 style-loader 和 css-loader 来处理{ test: /\.css$/, loader: 'style-loader!css-loader' },//.js 文件使用 jsx-loader 来编译处理{ test: /\.js$/, loader: 'jsx-loader?harmony' },//.scss 文件使用 style-loader、css-loader 和 sass-loader 来编译处理{ test: /\.scss$/, loader: 'style!css!sass?sourceMap'},//图片文件使用 url-loader 来处理,小于8kb的直接转为base64{ test: /\.(png|jpg)$/, loader: 'url-loader?limit=8192'} ] }
Loader
可以通过 npm 发布和安装。!
用来定义loader
的串联关系,”-loader”
是可以省略不写的,多个loader
之间用“!”连接起来,但所有的加载器都需要通过npm来加载。loaders
接受查询参数,可以用于传递配置项给loader
我们要在页面中引入一个 CSS 文件 style.css,首页将 style.css
也看成是一个模块,然后用 css-loader
来读取它,再用 style-loader
把它插入到页面中。
我们可以根据模块类型(扩展名)来自动绑定需要的 loader。
将 entry.js 中的 require("!style!css!./style.css")
修改为 require("./style.css")
,然后执行:
$ webpack entry.js bundle.js --module-bind 'css=style!css'
安装 loader:
npm install css-loader style-loader
resolve
webpack
在构建包的时候会按目录的进行文件的查找,resolve
属性中的extensions
数组中用于配置程序可以自行补全哪些文件后缀。extensions
第一个是空字符串,对应不需要后缀的情况.
externals
当我们想在项目中require一些其他的类库或者API,而又不想让这些类库的源码被构建到运行时文件中,
这在实际开发中很有必要。此时我们就可以通过配置externals参数来解决这个问题:
externals: { "jquery": "jQuery" }
这样我们就可以放心的在项目中使用这些API了:var jQuery = require(“jquery”)
;
常用命令
webpack 最基本的启动webpack命令webpack -w 提供watch方法,实时进行打包更新webpack -p 对打包后的文件进行压缩webpack -d 提供SourceMaps,方便调试webpack --colors 输出结果带彩色,比如:会用红色显示耗时较长的步骤webpack --profile 输出性能数据,可以看到每一步的耗时webpack --display-modules 默认情况下 node_modules 下的模块会被隐藏,加上这个参数可以显示这些被隐藏的模块
Webpack
开发服务器需要单独安装,同样是通过npm进行:
npm install -g webpack-dev-server
可以使用webpack-dev-server
直接启动,也可以增加参数来获取更多的功能,
具体配置可以参见官方文档。默认启动端口8080,通过 localhost:8080
可以访问页面,文件修改后保存时会在页面头部看到sever的状态变化,并且会进行热替换,实现页面的自动刷新。
当项目逐渐变大,webpack 的编译时间会变长,可以通过参数让编译的输出内容带有进度和颜色。
$ webpack --progress --colors
Webpack 的配置提供了 resolve
和 resolveLoader
参数来设置模块解析的处理细节,resolve
用来配置应用层的模块(要被打包的模块)解析,resolveLoader
用来配置 loader
模块的解析。
var webpack = require('webpack');module.exports = { entry: './entry.js',//入口文件 output:{ path: __dirname,//输出目录 filename: 'bundle.js'//输出文件名 }, //module 的作用是添加loaders module:{ loaders: [{ test:/\.css$/,//test属性匹配css文件 loader: 'style!css'//加载style和css loader} ] }, //Webpack 本身内置了一些常用的插件,还可以通过 npm 安装第三方插件。 plugins:[ new webpack.BannerPlugin('this file is created by trigkit4')//BannerPlugin 内置插件来实践插件的配置和运行,这个插件的作用是给输出的文件头部添加注释信息。 ], resolve: { fallback: path.join(__dirname, "node_modules") }, resolveLoader: { fallback: path.join(__dirname, "node_modules") }};
Webpack
中涉及路径配置最好使用绝对路径。
list of Loader
http://webpack.github.io/docs/list-of-loaders.html
Babel-loader can transform JSX/ES6 file into JS file
npm install babel-loader babel-core babel-preset-es2015 babel-preset-react --save-dev
你可以在webpack里require进来css文件,然后通过CSS-loader预处理css文件
webpack-dev-server
webpack-dev-server
是一个小型的node.js Express
服务器,它使用webpack-dev-middleware
中间件来为通过webpack
打包生成的资源文件提供Web服务。它还有一个通过Socket.IO
连接着webpack-dev-server
服务器的小型运行时程序。webpack-dev-server
发送关于编译状态的消息到客户端,客户端根据消息作出响应。
webpack-dev-server
有两种模式支持自动刷新——iframe
模式和inline
模式。在iframe
模式下:页面是嵌套在一个iframe下的,在代码发生改动的时候,这个iframe会重新加载;在inline
模式下:一个小型的webpack-dev-server
客户端会作为入口文件打包,这个客户端会在后端代码改变的时候刷新页面。
http://localhost:8080/webpack-dev-server/index.html
使用inline模式:命令行方式
1) 命令行方式比较简单,只需加入--line选项即可。例如:webpack-dev-server --inline
插件
webpack+reactjs的使用
webpack.config.js文件:
var webpack = require('webpack');var uglifyJsPlugin = webpack.optimize.UglifyJsPlugin;module.exports = { entry: './entry.jsx', output: { filename: 'bundle.js' }, module:{ loaders:[{test:/\.js[x]?$/,loader: 'babel-loader',exclude:/node_modules/,query:{ presets: ['es2015','react']} },{ test: /\.css$/, loader: 'style-loader!css-loader?modules'} ] }, plugins: [ new uglifyJsPlugin({compress: { warnings: false} }) ]};
package.json
文件
{ "name": "reactdemo", "version": "1.0.0", "description": "reactdemos", "main": "main.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "trigkit4", "license": "ISC", "dependencies": { "babel-preset-react": "^6.3.13", "react": "^0.14.5", "react-dom": "^0.14.5" }, "devDependencies": { "babel-core": "^6.3.26", "babel-loader": "^6.2.0", "babel-preset-es2015": "^6.3.13", "babel-preset-react": "^6.3.13", "webpack": "^1.12.9" }}
index.html
文件:
<!DOCTYPE html><html><head> <meta charset="UTF-8"> <title></title></head><body><div id="example"></div><script src="bundle.js"></script></body></html>
entry.jsx
文件
const React = require('react');const ReactDOM = require('react-dom');var style = require('./app.css');var Input = React.createClass({ getInitialState: function () { return{value: 'hello' } }, handleChange: function(event){ this.setState({value: event.target.value }) }, render: function(){ var value = this.state.value; return(<div> <input type="text" value={value} onChange={this.handleChange}/> <p>{a}</p></div> ) }});var a = React.createElement('a',{ className: 'link', href: 'https://www.baidu.com'},'React');//<a class='link' href='https://www.baidu.com'>React</a>ReactDOM.render( <Input/>, document.getElementById('example'));
app.css
文件
html{ font-size: 10px;}p{ font-size: 1.6rem;}input[type=text]{ color: red; font-size: 1.2rem;}
http://webpack.github.io/docs/list-of-plugins.html