探索vue-cli的webpack和webpack-simple模板的development server实现差别

之前初始化 vue工程都是用的 webapck的完整配置模板,即:
vue init webpack my-project
最近写一个简单的 vue组件,准备发布到 npm,所以决定使用更简洁的 webapck配置模板,即:
vue init webpack-simple my-project
初始化完成后,发现 index.html中多了对 build.js的引用,而 webapck的完整配置模板中的 index.html是没有对输出文件 build.js的引用的,这引发个人注意,决定看看为什么有这样的差别。

HtmlWebpackPlugin

最开始我认为完整版的webapck配置中使用了html-webpack-plugin插件,该插件会以index.html为模板,注入引用build.js<script src="/dist/build.js"></script>标签,所以不须要手动在index.html中引用build.js。所以我在简洁版webapck配置中添加了html-webpack-plugin插件,并删除index.html中对build.js的引用,发现并不生效。html

plugins: [
    new HtmlWebpackPlugin({
      filename: 'index.html',
      template: 'index.html',
      inject: true
    })
  ]

webpack-dev-server

查阅webpack-dev-server文档,发现有这样的描述:vue

It will not be written to your configured output directory. Where a bundle already exists at the same URL path, the bundle in memory takes precedence (by default).

大概意思是说,webpack-dev-server不会把打包出的文件写入硬盘,而是把打包文件保存在内存中,而且优先返回内存中的内容。根据这段描述,我执行npm run dev启动了服务器(端口8080),打开http://localhost:8080,能够正常访问。这时,个人工程中是没有dist文件夹的,打开http://localhost:8080/dist也能够正常访问;说明webpack-dev-server确实在内存中保存着输出文件,在浏览器请求时,webpack-dev-server返回了内存中的内容。
这下能够理解了,启动服务器后,打开http://localhost:8080,浏览器会默认去加载根目录下的index.html,而后再根据<script src="/dist/build.js"></script>标签去请求build.jswebpack-dev-server返回了内存中的build.js(这个时候,硬盘上并不存在build.js)。
若是index.html不引用build.js,浏览器就不会去请求build.js,页面不能正常显示。若是不想在index.html引用打包后的文件(好比每次打包文件名都是随机的),可使用html-webpack-harddisk-pluginhtml-webpack-plugin使webpack-dev-server具备向硬盘文件(index.html)注入script标签的能力,也能够在使用html-webpack-plugin的前提下将npm run dev执行的命令修改成:java

webpack --config webpack.config.js && webpack-dev-server --open --hot --content-base ./build

即先让webpack编译再让服务器返回编译结果,事实上vue-cli的完整版webpack配置模板就是这样作的。webpack

vue-cli的完整webpack配置模板中的development server实现

根据上面的分析,简洁版webpack配置中必须在index.html中引用build.js,页面才能正常显示,但为何完整webpack配置模板不须要引入呢。
经过查看完整webpack配置模板中的./build/dev-server.js能够看到,其实在完整版中vue-cli是本身用expresswebpack-dev-middlewarewebpack-hot-middleware等实现的development server,而不是用的webpack-dev-serverwebpack-dev-middleware使用webpack编译源文件并将结果保存在内存中,在浏览器请求资源时,返回内存中的内容;而且该模板中是使用了html-webpack-plugin的,在编译的时候已经在index.html中注入了build.js的引用,所以不须要事先在index.html写好build.js的引用。git

总结

  • webpack-dev-server不具有向硬盘文件(index.html)注入script标签的能力,只能事先在index.html中写好对build.js的引用。
  • vue-cli的完整webpack配置模板,采用的策略是用webpack-dev-middleware先编译源文件并保存在内存中(使用html-webpack-plugin注入js引用),再返回给浏览器。
  • vue-cli的完整webpack配置模板是基于express构建的服务器,没有使用webpack-dev-server

其它

在开发的过程当中,我发现vue-cli的简洁webpack配置模板在开发模式下,不会把es6语法转换为es5语法,而执行打包操做时却会转换。vue-cli的完整webpack配置模板不存在这个问题。
webpack-dev-server的issues中,有人说,因为是在命令行启动、配置的webpack-dev-serverwebpack会到全局查找babel配置,本地的babel不生效,从而致使语法转换失败。
我我的并无找到确切缘由,望知情人指点。es6

相关文章
相关标签/搜索