webpack-dev-server,iframe与inline的区别


http://blog.csdn.net/chengnuo628/article/details/52441977

 

记录下 webpack-dev-server 的用法.

首先,我们来看看基本的 webpack.config.js 的写法

module.exports = {
        entry: './src/js/index.js', output: { path: './dist/js', filename: 'bundle.js' } }

配置文件提供一个入口和一个出口, webpack 根据这个来进行 js的打包和编译工作。虽然 webpack 提供了 webpack --watch 的命令来动态监听文件的改变并实时打包,输出新 bundle.js 文件,这样文件多了之后打包速度会很慢,此外这样的打包的方式不能做到 hot replace ,即每次 webpack 编译之后,你还需要手动刷新浏览器。

webpack-dev-server 其中部分功能就能克服上面的2个问题。 webpack-dev-server 主要是启动了一个使用 express 的 Http服务器 。它的作用 主要是用来伺服资源文件 。此外这个 Http服务器 和 client 使用了 websocket 通讯协议,原始文件作出改动后, webpack-dev-server 会实时的编译,但是最后的编译的文件并没有输出到目标文件夹,即上面配置的。

注意:你启动webpack-dev-server后,你在目标文件夹中是看不到编译后的文件的,实时编译后的文件都保存到了内存当中。因此很多同学使用webpack-dev-server进行开发的时候都看不到编译后的文件

下面来结合 webpack 的文档和 webpack-dev-server 里部分源码来说明下如何使用:

启动

启动 webpack-dev-server 有2种方式:

cmd line
Node.js API

配置

我主要讲解下 cmd line 的形式, Node.js API 形式大家去看下官方文档。可通过 npm script 进行启动。我的目录结构是:

app
    |__dist
    |   |__styles
    |   |__js
    |       |__bundle.js
    |   |__index.html
    |__src
    |   |__styles
    |   |__js
    |       |__index.js |__node_modules |__package.json |__webpack.config.js

content-base

设定 webpack-dev-server 伺服的 directory 。如果不进行设定的话,默认是在当前目录下。

webpack-dev-server --content-base ./dist

这个时候还要注意的一点就是在 webpack.config.js 文件里面,如果配置了 output 的 publicPath 这个字段的值的话,在 index.html 文件里面也应该做出调整。 因为 webpack-dev-server 伺服的文件是相对 publicPath 这个路径的 。因此,如果你的 webpack.config.js 配置成这样的:

module.exports = {
        entry: './src/js/index.js', output: { path: './dist/js', filename: 'bundle.js', publicPath: '/assets/' } }

那么,在 index.html 文件当中引入的路径也发生相应的变化:

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

如果在 webpack.config.js 里面没有配置 output 的 publicPath 的话,那么index.html 最后引入的文件 js文件 路径应该是下面这样的。

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

Automatic Refresh

webpack-dev-server 支持2种自动刷新的方式:

  • Iframe mode

  • inline mode

这2种模式配置的方式和访问的路径稍微有点区别,最主要的区别还是 Iframe mode 是在网页中嵌入了一个 iframe ,将我们自己的应用注入到这个 iframe 当中去,因此每次你修改的文件后,都是这个 iframe 进行了 reload 。

通过查看 webpack-dev-server 的源码, lib 路径下的 Server.js 文件,第38-48行,分别新建几个流,这几个流保存了 client 文件夹下的相关文件:

// Prepare live html page
    var livePage = this.livePage = new StreamCache(); fs.createReadStream(path.join(__dirname, "..", "client", "live.html")).pipe(livePage); // Prepare the live js file var liveJs = new StreamCache(); fs.createReadStream(path.join(__dirname, "..", "client", "live.bundle.js")).pipe(liveJs); // Prepare the inlined js file var inlinedJs = new StreamCache(); fs.createReadStream(path.join(__dirname, "..", "client", "index.bundle.js")).pipe(inlinedJs);
// Init express server
    var app = this.app = new express(); // middleware for serving webpack bundle this.middleware = webpackDevMiddleware(compiler, options); app.get("/__webpack_dev_server__/live.bundle.js", function(req, res) { res.setHeader("Content-Type", "application/javascript"); liveJs.pipe(res); }); app.get("/webpack-dev-server.js", function(req, res) { res.setHeader("Content-Type", "application/javascript"); inlinedJs.pipe(res); }); app.get("/webpack-dev-server/*", function(req, res) { res.setHeader("Content-Type", "text/html"); this.livePage.pipe(res); }.bind(this));

当使用 Iframe mode 时,请求 /webpack-dev-server/index.html 路径时,会返回 client/index.html 文件,这个文件的内容就是:

<!DOCTYPE html><html><head><meta http-equiv="X-UA-Compatible" content="IE=edge"/><meta charset="utf-8"/><meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"/><script type="text/javascript" charset="utf-8" src="/__webpack_dev_server__/live.bundle.js"></script></head><body></body></html>

这个页面会请求 live.bundle.js ,其中里面会新建一个 Iframe ,你的应用就被注入到了这个 Iframe 当中。同时 live.bundle.js 中含有 socket.io 的 client 代码,这样它就能和 webpack-dev-server 建立的 http server 进行 websocket 通讯了。并根据返回的信息完成相应的动作。

而 Inline-mode ,是 webpack-dev-server 会在你的 webpack.config.js 的入口配置文件中再添加一个入口,

module.exports = {
        entry: { app: [ 'webpack-dev-server/client?http://localhost:8080/', './src/js/index.js' ] }, output: { path: './dist/js', filename: 'bundle.js' } }

这样就完成了将 inlinedJS 打包进 bundle.js 里的功能,同时 inlinedJS 里面也包含了 socket.io 的 client 代码,可以和 webpack-dev-server 进行 websocket 通讯。

当然你也可以直接在你 index.html 引入这部分代码:

<script src="http://localhost:8080/webpack-dev-server.js"></script>

不过 Iframe mode 和 Inline mode 最后达到的效果都是一样的,都是监听文件的变化,然后再将编译后的文件推送到前端,完成页面的 reload 的。

Iframe mode

Iframe mode 下 cmd line 不需要添加其他的内容,浏览器访问的路径是:

localhost:8080/webpack-dev-server/index.html。

这个时候这个页面的 header部分 会出现整个 reload消息 的状态。当时改变源文件的时候,即可以完成自动编译打包,页面自动刷新的功能。

Inline mode

使用 inline mode 的时候, cmd line 需要写成:

webpack-dev-server --inline --content-base ./dist

这个时候访问的路径是:

localhost:8080/index.html

也能完成自动编译打包,页面自动刷新的功能。但是没有的 header 部分的 reload 消息的显示,不过在控制台中会显示 reload 的状态。

Hot Module Replacement

开启 Hot Module Replacemen t功能,在 cmd line 里面添加 --hot

webpack-dev-server --hot --inline --content-base ./dist

其他配置选项

--quiet 控制台中不输出打包的信息
--compress 开启gzip压缩 --progress 显示打包的进度

还有一切其他的配置信息可以查阅官方文档:

webpack-dev-server-cli

这是我的 package.json 的文件:

{
  "name": "reptile", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "dev": "webpack-dev-server --devtool eval-source-map --progress --colors --hot --inline --content-base ./dist", "build": "webpack --progress --colors" }, "author": "", "license": "ISC", "devDependencies": { "babel-core": "^6.13.2", "babel-loader": "^6.2.5", "babel-preset-es2015": "^6.13.2", "babel-preset-react": "^6.11.1", "css-loader": "^0.23.1", "react": "^15.3.1", "react-dom": "^15.3.1", "style-loader": "^0.13.1", "webpack": "^1.13.2", "webpack-dev-server": "^1.14.1" } }

首先命令行:输入 npm install 所有依赖。然后输入 npm run dev 。在浏览器中打开localhost:8080/index.html,然后就可以愉快的开发咯。

如果对 web-dev-server 还有其他问题的话,请留言告知。


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM