来自 美高梅4858永利777 2019-12-21 21:40 的文章
当前位置: 美高梅游戏平台网站 > 美高梅4858永利777 > 正文

浅谈Vue SSR中的Bundle的具有使用_vue.js_脚本之家

前言

Webpack作为非常受欢迎的前端工具,必然有它的厉害之处。所以单独开篇文章记录学习Webpack的使用要点,主要分以下几部分学习:

  • 后起之秀为何这么受欢迎?

写过Vue SSR的都知道,Vue通过提供server和client的webpack插件生成bundle josn,从而实现类似服务端的热更以及客户端资源的优化注入。那么这两个个bundle到底有什么神奇的呢?OK,话不多说,进入正题

  • webpack的安装和基本工作流程
  • 如何使用loaders
  • 使用Webpack进行vue组件化开发
  • webpack的常用命令行及热加载
  • webpack的插件和配置文件的最佳实践
  • webpack的两个分析工具

客户端 vue-ssr-client-manifest.json


首先看看客户端的json,明显看到,里面借助webpack插件,把spa用到的文件进行了分类, publicPath 是公共路径,all 是所有的文件, initial 是入口文件依赖的js和css, async 是首屏不需要的异步的js,分析这些出来有什么用呢,主要是用来优化生成的html的资源注入,这个在后面会讲到

1.后起之秀为何这么受欢迎?

webpack之前有gulp、require等构件工具,但仍然会迅速的成为最受欢迎的前端构建工具。主要是因为他在减少http请求和静态文件体积两方面做的更好,此外还有很多灵活的插件和loader机制。

服务端 vue-ssr-server-bundle.json

2.webpack的安装和基本工作流程

![](https://upload-images.jianshu.io/upload_images/1292864-74502f3f6d5e63ca.png)
  • 工作流程示例:
    创建moduleOne.js

    console.log('Module one')
    

创建moduleTwo.js

  console.log('Module two')

入口文件entry.js

  require('./module-one.js');
  require('./module-two.js');

使用webpack打包命令生成bundle.js

webpack js/entry.js bundle.js

在客户端客户端页面index.html中引入bundle.js

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Webpack learning</title>
    </head>
    <body>
        <h1>Webpack is nice!</h1>
        <script src="bundle.js"></script>
    </body>
</html>

这样最简单的打包示例就完成了。

实际项目中一般不直接在命令行中配置入口和出口文件来进行打包,而是通过配置文件webpack.config.js来控制,OK!我们创建一个webpack.config.js文件。

module.exports = {
  devtool:"sourcemap",
  entry:"./js/entry.js",
  output: {
      filename: "bundle.js"
  }
};

其中devtool声明文件映射关系、entry和output分别声明入口和出口文件。然后通过webpack命令直接打包。

bogon:webpack-learning chengyanfang$ webpack
Hash: 2ff33cd9e057fd7d476f
Version: webpack 2.2.1
Time: 92ms
      Asset     Size  Chunks             Chunk Names
      bundle.js  3.04 kB       0  [emitted]  main
      bundle.js.map  3.37 kB       0  [emitted]  main
      [0] ./js/module-one.js 73 bytes {0} [built]
      [1] ./js/module-two.js 73 bytes {0} [built]
      [2] ./js/entry.js 104 bytes {0} [built]

此时工程中除了生成bundle.js 还生成了 bundle.js.map。

接下来引用jquery来扩展moduleOne的功能,进入项目目录:

npm init  //初始化npm
npm install jquery --save-dev  //引入jquery

然后修改moduleOne.js

//声明jquery的$变量
var $ = require("jquery");

//执行jquery命令,替换index.html的h1元素内容
$('h1').html('It is real');

然后webpack重新打包测试,顺利完成目标。
此时jquery只是在moduleOne.js中存在,而不是全局存在,这正是webpack的魅力所在。

然后我们再康康服务端生成的json, entry 是服务款入口的文件, files 是服务端依赖的文件列表, maps 是sourcemaps文件列表,这里暂时是空

3.如何使用loaders

正如上节示例所示,webpack的强大之处在于几乎可以把所有的静态文件打包到一个js文件里。然后他会使用各种loader来解析这个js文件的内容。所以这节主要学习各种loader。

首先,通过npm下载css-loader和style-loader

npm install css-loader style-loader --save -dev

然后,在webpack配置文件中声明,某个类型的文件需要使用某个类型的loader来处理。修改webpack.config.js如下:

module.exports = {
  devtool:"sourcemap",
  entry:"./js/entry.js",
  output: {
      filename: "bundle.js"
  },
  module: {
    loaders:[
        {
            test:/.css$/,
            loader:"style-loader!css-loader"
        }
    ]
  }
};

然后,创建一个style.css文件用于测试:

body{
  background: cornflowerblue;
}

之后在entry.js中把style.css包含进来:

//css
require('../css/style.css');

这样css文件就会通过webpack打包进bundle.js,然后在index.html中引入bundle.js 进而style.css成功渲染index.html的body....(瞅瞅我这英文讲的)。重新打包测试,成功OK!

接下来使用有关es6种关于babel的loader:

npm install babel-core babel-loader babel-plugin-transform-runtime babel-preset-es2015 babel-preset-stage-0 babel-runtime --save-dev

然后在webpack.config.js中增加babel的loader配置(使得除node_modules下的js文件之外,其余全部使用ES6的语法处理js文件):

{
    test:/.js$/,
    loader:"babel-loader",
    exclude:/node_modules/
}

同时需要在更目录增加.babelrc文件进行babel设置:

{
  presets: ['es2015','stage-0'],
  plugins: ['transform-runtime']
}

然后webpack打包测试,成功OK!

如果把files展开,会看到里面是一堆文件列表,文件名跟key一样,然后value里面,对的,你没看错,是一段js,里面就是服务端渲染需要的代码,那道理我都懂,为什么有这段就可以实现服务端代码的热更以及sourcemap的定位呢

4.使用Webpack进行vue组件化开发

首先通过npm安装vue相关的loader

npm install vue vue-loader vue-html-loader vue-style-loader vue-template-compiler --save-dev

接着配置webpack.config.js中的loader:

{
    test:/.vue$/,         
    loader:"vue-loader"
}

然后创建heading.vue文件:

 <template>
    <div>
        <h1>Hello {{message}}</h1>
    </div>
 </template>

 <script>
    export default{
        data(){
            return{
                message:'vue.js'
            }
        }
    }
 </script>

然后在entry.js中引入heading.vue

 //vue
import Vue from 'vue'
import Heading from './components/heading.vue';
new Vue({
  el:"#app",
  components : {Heading}
});

之后在index.html中引入Heading组件:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Webpack learning</title>
</head>
<body>
    <div id="app">
        <Heading></Heading>
    </div>

    <h1>Webpack is nice!</h1>
    <script src="bundle.js"></script>
</body>
</html>

最后还要配置webpack.config.js 来避免运行时问题,完整配置如下:

module.exports = {
    devtool:"sourcemap",
    entry:"./js/entry.js",
    output: {
        filename: "bundle.js"
    },
    module: {
        loaders:[
            {
                test:/.css$/,
                loader:"style-loader!css-loader"
            },
            {
                test:/.js$/,
                loader:"babel-loader",
                exclude:/node_modules/
            },
            {
                test:/.vue$/,
                loader:"vue-loader"
            }
        ]
    },
    resolve: {
        alias: {
            'vue$': 'vue/dist/vue.js'
        }
    }
};   

最后webpack打包测试,成功OK!

服务端的热更和sourcemap

5.webpack的常用命令行及热加载

优化及文件压缩命令,对于线上部署时非常有用

webpack -p

使用watch机制,实时监控源码修改,而不需要每次都执行webpack;一次执行之后,每次更新代码只需要刷新下浏览器即可。

webpack -w

更进一步,webpack还提供修改代码后不需要刷新浏览器就可以实时查看效果的热更新技术,通过以下步骤进行配置:

首先,全局安装webpack-dev-serve

npm install webpack-dev-server -g

然后进入到项目目录再次执行
npm install webpack --save-dev

最后执行以下命令启动localhost服务器,并且设置flag为热加载

webpack-dev-server --inline --hot

打开http://localhost:8080/,修改代码测试,成功OK!

带着这个问题,我去看了一下vue服务端的源码,左边框的三个文件就是实现这些神奇效果的关键之处了,其中右边框的entry、files就是我们上面服务端对应的json

6.webpack的插件和配置文件的最佳实践

首先获取当前环境变量

  var debug = process.env.NODE_ENV != "production"

然后做如下差异化配置:

  • 线上环境时不需要生成sourcemap

    devtool:debug ? "sourcemap" : null,
    
  • 线上环境时增加一些压缩和优化的插件 (插件列表查询地址)

   plugins:debug ? [] : [
    new webpack.optimize.DedupePlugin(),
    new webpack.optimize.OccurenceOrderPlugin(),
    //UglifyJsPlugin混淆作用
    new webpack.optimize.UglifyJsPlugin({mangle:false,sourcemap:false}),
  • 最终的webpack.config.js文件内容
    var debug = process.env.NODE_ENV != "production"

    module.exports = {
        devtool:debug ? "sourcemap" : null,
        entry:"./js/entry.js",
        output: {
            filename: "bundle.js"
        },
        module: {
            loaders:[
                {
                    test:/.css$/,
                    loader:"style-loader!css-loader"        
                },
                {
                    test:/.js$/,
                    loader:"babel-loader",
                    exclude:/node_modules/
                },
                {
                    test:/.vue$/,
                    loader:"vue-loader"
                }
            ]
        },
        plugins:debug ? [] : [
            new webpack.optimize.DedupePlugin(),
            new webpack.optimize.OccurenceOrderPlugin(),
            new webpack.optimize.UglifyJsPlugin({mangle:false,sourcemap:false}),
        ],
        resolve: {
            alias: {
                'vue$': 'vue/dist/vue.js'
            }
        }
    };

接下来我们再去看看createBundleRunner里面这个方法,最关键是evaluateModule 里面调用getCompiledScript这个方法,其中evaluateModule 还会把执行的结果缓存到evaluatedFiles里面去

7.webpack的两个分析工具

  • #### Analyse工具

    Analyse工具用来分析整个项目中的引用package及之间关系。使用方式如下:

    首先生成用来分析的stats.json文件到项目目录下:

      webpack --profile --json > stats.json
    

    然后打开 (analyse分析工具)上传stats.json进而查看整个项目的信息。

getCompiledScript里面通过调用vm.Scirpt把我们在entry里面的代码丢进vm创建的沙箱里面,同时也是要compiledScripts把生成的script片段缓存起来

本文由美高梅游戏平台网站发布于美高梅4858永利777,转载请注明出处:浅谈Vue SSR中的Bundle的具有使用_vue.js_脚本之家

关键词: