精华内容
下载资源
问答
  • 4、发起请求、获取数据,渲染内容 下面我们主要是讨论一下如何通过预渲染的方式降低空白屏的时间 二、传统页面开发 在React、Vue这种数据驱动的框架还没盛行的时候,一般我们都是直接在html上写dom结构的,要不就是...

    一、浏览器渲染过程

    1、用户打开页面,空白屏,等待html的返回

    2、html下载完毕,开始解析html,初始渲染

    3、下载css、js等资源,执行js渲染虚拟DOM

    4、发起请求、获取数据,渲染内容

    下面我们主要是讨论一下如何通过预渲染的方式降低空白屏的时间

    二、传统页面开发

    在React、Vue这种数据驱动的框架还没盛行的时候,一般我们都是直接在html上写dom结构的,要不就是直接服务端直出,所以我们在下载完html页面后,空白屏的时间是非常短的,因为dom是在html中的,并不是像现在以虚拟dom的方式写在js中,所以,我们不需要等待js下载完毕后才开始渲染页面,而是html下载完毕后直接渲染出dom结构。

    如今我们运用Vue等框架进行开发的时候,一般在html结构都是下面这样的

    <!DOCTYPE html>
    <html lang="en">
        <head>
          <meta charset="UTF-8">
          <title>title</title>
        </head>
        <body>
          <div id="app"></div>
          <script src="/bound.js"></script>
        </body>
    </html>
    复制代码

    在js资源没有下载完毕的情况下,页面一直都是处于空白的页面,一直要等到虚拟dom插入到id为app的div中,这时候白屏才消失开始展现页面,反正就是让人感觉特别慢就是了!

    既然知道了白屏是怎么产生的,那我们下面就来尝试一下如何在webpack中集成预渲染的功能,来降低白屏的时间。

    三、在webpack中集成预渲染功能

    github:webpack中如何集成预渲染功能

    这里我们尝试将一个使用vue编写的loading组件在webpack编译过程中将虚拟dom预渲染到html中,下面是loading组件的内容

    <template>
      <div class="loading-img"></div>
    </template>
    
    <script>
    export default {}
    </script>
    
    <style>
    .loading-img {
      position: fixed;
      top: 0;
      bottom: 0;
      right: 0;
      left: 0;
      margin: auto;
      display: inline-block;
      width: 60px;
      height: 60px;
      background: url(__inline__) no-repeat center center;
      background-size: contain;
    }
    </style>
    复制代码

    上面__inline__是用于后面图片插入的标记,这里先不用管,其实这个组件就是一个简单的loading组件

    最终我们想要的效果是,将这个vue组件的虚拟dom预渲染到html文件当中

    <html>
      <head>
        <meta charset="UTF-8">
        <title>test</title>
        <!-- pre-render-loading抽出的css -->
        <style>
          .loading-img {
            position: fixed;
            top: 0;
            bottom: 0;
            right: 0;
            left: 0;
            margin: auto;
            display: inline-block;
            width: 60px;
            height: 60px;
            <!-- 这里我们会将loading图编译成base64直接插入到html中 -->
            background: url(data:image/gif;base64,.....) no-repeat center center;
            background-size: contain;
          }
        </style>
        ...
      </head>
    
      <body>
        <div id="app">
          <!-- loading base64图 -->
          <div class="loading-img"></div>
        </div>
        
        ...
      </body>
    </html>
    复制代码

    向上面那样,在html页面返回时编译成base64内嵌到html中的loading就会马上显示,大大降低了白屏的时间,基本可以达到秒开页面,这时候我们不需要等待js资源的下载以及虚拟dom的插入,当然这里loading中的内容可以是任何你想要预先渲染的模板

    因为这里我们的loading组件是用vue写的,所以我们试着看看如何来做预渲染并集成到webpack中(可以合着仓库的代码一起看,代码挺简单的,只是一个demo)

    这里我们先把vue单文件中的html与css单独抽离出来

    // render-loading.js
    
    let vueAssets = null
    let vueTplPath = resolvePath('./src/loading/pre-render-loading.vue')
    
    const extractAssetsInVueTpl = (vueTplPath) => {
      let vueTpl = clearEnter(fs.readFileSync(vueTplPath).toString())
      let html = /<template>(.*)<\/template>/g.exec(vueTpl)[1]
      let css = /<style>(.*)<\/style>/g.exec(vueTpl)[1]
    
      return {
        html,
        css
      }
    }
    
    vueAssets = extractAssetsInVueTpl(vueTplPath)
    复制代码

    这里我们通过正则的方式将template与style标签中匹配到的内容单独抽离了出来,接下来我们需要将gif图转成base64并插入到我们抽出的css代码当中

    let gifPath = resolvePath('./src/loading/imgs/loading.gif')
    
    const transGifToCSSFile = (imgPath) => {
      let ext = path.extname(imgPath).slice(1)
      let preStr = `data:image/${ext};base64,`  // 根据尾缀自动拼接对应base64前缀
      let bitDate = fs.readFileSync(imgPath)
      let base64Str = bitDate.toString('base64')
      let dataURL = preStr + base64Str
    
      return dataURL
    }
    
    let dataURL = transGifToCSSFile(gifPath)
    复制代码

    上面我们通过extractAssetsInVueTpl函数抽离出了css,这里我们通过一个简单的函数将占位符替换成base64图片

    const injectDataURLToCSS = (cssStr, dataURL) => {
      return cssStr.replace(/__inline__/, dataURL)
    }
    
    let cssStr = injectDataURLToCSS(vueAssets.css, dataURL)
    复制代码

    下面我们就导出loading配置,包含了html模板与style样式字符串

    loading.html = vueAssets.html
    loading.css = '<style>' + cssStr + '</style>'
    
    module.exports = loading
    复制代码

    简单写一个webpack入口配置,这里我们需要使用html-webpack-plugin将loading插入到html中(这里用到了插件的自定义模板)

    const HtmlWebpackPlugin = require('html-webpack-plugin')
    const loading = require('./render-loading')
    
    module.exports = {
      entry: './src/index.js',
      output: {
        path: __dirname + '/dist',
        filename: 'index_bundle.js'
      },
      plugins: [
        new HtmlWebpackPlugin({
          template: './src/index.html',
          loading: loading
        })
      ]
    }
    复制代码

    在html中我们通过模板语法将loading的内容插入到html模板中对应的位置了

    <html>
      <head>
        <meta charset="UTF-8">
        <title>test</title>
        ...
        <%= htmlWebpackPlugin.options.loading.css %>
      </head>
    
      <body>
        <div id="app">
          <!-- loading base64图 -->
          <%= htmlWebpackPlugin.options.loading.html %>
        </div>
        
        ...
      </body>
    </html>
    复制代码

    四、总结

    这里只是写一个demo介绍一下原理,更复杂的可以使用vue-server-render来做同构直出或者使用一些像handlebars的模板引擎来生成模板,其实就是将服务端的渲染工作放到了编译的过程当中。

    展开全文
  • webpack+vue中,如何将css相同的部分提取到一个公共的common.css中?var webpack = require('webpack');var ExtractTextPlugin =require("extract-text-webpack-plugin");module.exports = {//插件项plugins: [new...

    在webpack+vue中,如何将css相同的部分提取到一个公共的common.css中?

    var webpack = require('webpack');

    var ExtractTextPlugin =require("extract-text-webpack-plugin");

    module.exports = {

    //插件项

    plugins: [

    new webpack.optimize.CommonsChunkPlugin({

    name: "common",

    filename: "common.js",

    minChunks: 5,

    }),

    new ExtractTextPlugin("[name].css"),

    new webpack.ProvidePlugin({

    $: "jquery",

    jQuery: "jquery",

    Vue: "Vue",

    })

    ],

    //页面入口文件配置

    entry: {

    // 这里有很多个各个界面的模块

    },

    //入口文件输出配置

    output: {

    path: 'dist/test',

    filename: '[name].js'

    },

    module: {

    //加载器配置

    loaders: [

    { test: /\.css$/, loader: ExtractTextPlugin.extract("style-loader", "css-loader?sourceMap") },

    { test: /\.less$/, loader: ExtractTextPlugin.extract("style-loader", "css-loader!less-loader") },

    { test: /\.(png|jpg)$/, loader: 'url-loader?limit=8192' },

    { test: /\.(gif|jpg|png)\??.*$/, loader: 'url-loader?limit=20000&name=images/[name].[ext]'},

    { test: /\.(woff|svg|eot|ttf)\??.*$/, loader: 'url-loader?limit=1&name=fonts/[name].[ext]'},

    { test: /\.vue$/, loader: 'vue-loader'},

    ]

    },

    vue: {

    loaders: {

    css: ExtractTextPlugin.extract("style-loader", "css-loader?sourceMap"),

    less: ExtractTextPlugin.extract("style-loader", "css-loader!less-loader")

    }

    },

    resolve: {

    alias: {

    "jquery": __dirname + "/vendor/bower/jquery/dist/jquery.min",

    "Vue": __dirname + "/vendor/bower/vue/dist/vue",

    // 还有各种外部库

    }

    },

    };

    现在这个配置文件打包的结果是:

    js有独立的common.js,每个入口都有出去公共模块的js,这是没问题的;但是css却有这样的错误:common.css里面虽然是公共的内容,但是每一个入口的css都包含所有的css,没有除去公共模块

    展开全文
  • 现在是单独import进来的样式文件可以单独提取出来,而在vue组件中的...完整配置信息,可以将Vue组件的CSS提取出来了,webpack.config.js:var ExtractTextPlugin = require('extract-text-webpack-plugin');module....

    现在是单独import进来的样式文件可以单独提取出来,而在vue组件中的样式还是跟js打包到一块儿的,要怎么才能把vue组件中的样式也单独提取出来放到一个外部的样式文件中呢?

    完整配置信息,可以将Vue组件的CSS提取出来了,webpack.config.js:

    var ExtractTextPlugin = require('extract-text-webpack-plugin');

    module.exports = {

    entry: './js/main.js',

    output: {

    path: __dirname,

    filename: '../static/js/app.js',

    },

    module: {

    loaders: [

    {

    test: /\.vue$/,

    loader: 'vue',

    },

    {

    test: /\.js$/,

    loader: 'babel',

    },

    {

    test: /\.(png|jpg)$/,

    loader: 'url?limit=8192',

    },

    {

    test: /\.css$/,

    loader: ExtractTextPlugin.extract('style-loader', 'css-loader'),

    },

    {

    test: /\.scss$/,

    loader: ExtractTextPlugin.extract('style-loader', 'css-loader!sass-loader'),

    },

    ],

    },

    vue: {

    loaders: {

    sass: ExtractTextPlugin.extract('vue-style-loader', 'css-loader!sass-loader'),

    },

    },

    plugins: [

    new ExtractTextPlugin('../static/css/style.css', {

    allChunks: true,

    }),

    ],

    };

    vue组件:

    @import "../../scss/_css3Module.scss";

    @import "../../scss/_retinaLine.scss";

    .help-title {

    margin: 0;

    }

    .help-title,

    .help-item {

    display: block;

    padding: 10px;

    text-align: center;

    background-color: #f1f1f1;

    margin-bottom: 5px;

    }

    h1.help-title 常用Vue组件

    a.help-item

    Geo

    a.help-item(@click='modalShowEvent(true, false)') 两按钮的弹框

    a.help-item(@click='modalShowEvent(true, true)') 一个按钮的弹框

    a.help-item(@click='modalShowEvent(true, false, "one")') 弹框确认事件1

    a.help-item(@click='modalShowEvent(true, true, "two")') 弹框确认事件2

    modal(v-show='modalToggle')

    p(slot='content') 这是外边的内容

    import Geo from './common/geolocation.vue';

    import Modal from './common/modal.vue';

    import { modalShowEvent } from '../store/actions/modal';

    import { modalToggle, modalCancelBtn } from '../store/getters';

    export default {

    components: {

    Geo,

    Modal,

    },

    vuex: {

    getters: {

    modalToggle,

    },

    actions: {

    modalShowEvent,

    },

    },

    }

    展开全文
  • 另请查看官方Webpack 4文档以获取正确的TypeScript设置: ://webpack.js.org/guides/typescript/ 注意,这仍然是一个在制品。 欢迎贡献/建议 :grinning_face_with_big_eyes: 产品特点 Webpack 4 TypeScript 2...
  • webpack如何调用插件,将插件中的方法在编译阶段注册到钩子上的呢? 对于这个问题,webpack规定每个插件的实例,必须有一个<code>.apply()方法,webpack打包前会调用所有插件的...
  • 最近在看 webpack 如何做持久化缓存的内容,发现其中还是有一些坑点的,正好有时间就将它们整理总结一下,读完本文你大致能够明白: 什么是持久化缓存,为什么做持久化缓存? webpack 如何做持久化缓存? webpack ...
  • webpack 持久化缓存

    2019-05-22 12:05:44
    首先我们需要去解释一下,什么是持久化缓存,在现在前后端分离的应用大行其道的背景下,前端 html,css,js 往往是以一种静态资源文件的形式存在于服务器,通过接口来获取数据来展示动态内容。这就涉及到公司如何去...

    前言

    1. 什么是持久化缓存,为什么做持久化缓存?
    2. webpack 如何做持久化缓存?

    持久化缓存

    首先我们需要去解释一下,什么是持久化缓存,在现在前后端分离的应用大行其道的背景下,前端 html,css,js 往往是以一种静态资源文件的形式存在于服务器,通过接口来获取数据来展示动态内容。这就涉及到公司如何去部署前端代码的问题,所以就涉及到一个更新部署的问题,是先部署页面,还是先部署资源?

    • 先部署页面,再部署资源:在二者部署的时间间隔内,如果有用户访问页面,就会在新的页面结构中加载旧的资源,并且把这个旧版本资源当做新版本缓存起来,其结果就是:用户访问到一个样式错乱的页面,除非手动去刷新,否则在资源缓存过期之前,页面会一直处于错乱的状态。
    • 先部署资源,再部署页面:在部署时间间隔内,有旧版本的资源本地缓存的用户访问网站,由于请求的页面是旧版本,资源引用没有改变,浏览器将直接使用本地缓存,这样属于正常情况,但没有本地缓存或者缓存过期的用户在访问网站的时候,就会出现旧版本页面加载新版本资源的情况,导致页面执行错误。

    所以我们需要一种部署策略来保证在更新我们线上的代码的时候,线上用户也能平滑地过渡并且正确打开我们的网站。

    推荐先看这个回答:大公司里怎样开发和部署前端代码?

    当你读完上面的回答,大致就会明白,现在比较成熟的持久化缓存方案就是在静态资源的名字后面加 hash 值,因为每次修改文件生成的 hash 值不一样,这样做的好处在于增量式发布文件,避免覆盖掉之前文件从而导致线上的用户访问失效。

    因为只要做到每次发布的静态资源(css, js, img)的名称都是独一无二的,那么我就可以:

    • 针对** html 文件**:不开启缓存,把 html 放到自己的服务器上,关闭服务器的缓存,自己的服务器只提供 html 文件和数据接口
    • 针对静态的 js,css,图片等文件:开启 cdn 和缓存,将静态资源上传到 cdn 服务商,我们可以对资源开启长期缓存,因为每个资源的路径都是独一无二的,所以不会导致资源被覆盖,保证线上用户访问的稳定性。静态资源放置于独立域名之下的好处
    • 每次发布更新的时候,先将静态资源(js, css, img) 传到 cdn 服务上,然后再上传 html 文件,这样既保证了老用户能否正常访问,又能让新用户看到新的页面。

    上面大致介绍了下主流的前端持久化缓存方案,那么我们为什么需要做持久化缓存呢?

    • 用户使用浏览器第一次访问我们的站点时,该页面引入了各式各样的静态资源,如果我们能做到持久化缓存的话,可以在 http 响应头加上 Cache-control 或 Expires 字段来设置缓存,浏览器可以将这些资源一一缓存到本地。
    • 用户在后续访问的时候,如果需要再次请求同样的静态资源,且静态资源没有过期,那么浏览器可以直接走本地缓存而不用再通过网络请求资源。

    webpack 如何做持久化缓存

    上面简单介绍完持久化缓存,下面这个才是重点,那么我们应该如何在 webpack 中进行持久化缓存的呢,我们需要做到以下两点:

    • 保证 hash 值的唯一性,即为每个打包后的资源生成一个独一无二的 hash 值,只要打包内容不一致,那么 hash 值就不一致。
    • 保证 hash 值的稳定性,我们需要做到修改某个模块的时候,只有受影响的打包后文件 hash 值改变,与该模块无关的打包文件 hash 值不变。

    hash 文件名是实现持久化缓存的第一步,目前 webpack 有两种计算 hash 的方式([hash] 和 [chunkhash])

    • hash 代表每次 webpack 在编译的过程中会生成唯一的 hash 值,在项目中任何一个文件改动后就会被重新创建,然后 webpack 计算新的 hash 值
    • chunkhash 是根据模块计算出来的 hash 值,所以某个文件的改动只会影响它本身的 hash 值不会影响其他文件。

    所以如果你只是单纯地将所有内容打包成同一个文件,那么 hash 就能够满足你了,如果你的项目涉及到拆包,分模块进行加载等等,那么你需要用 chunkhash,来保证每次更新之后只有相关的文件 hash 值发生改变。

    所以我们在一份具有持久化缓存的 webpack 配置应该长这样:

    module.exports = {
     entry: __dirname + '/src/index.js',
     output: {
     path: __dirname + '/dist',
     filename: '[name].[chunkhash:8].js',
     }
    }
    复制代码

    上面代码的含义就是:以 index.js 为入口,将所有的代码全部打包成一个文件取名为 index.xxxx.js 并放到 dist 目录下,现在我们可以在每次更新项目的时候做到生成新命名的文件了。

    如果是应付简单的场景,这样做就够了,但是在大型多页面应用中,我们往往需要对页面进行性能优化:

    • 分离业务代码和第三方的代码:之所以将业务代码和第三方代码分离出来,是因为业务代码更新频率高,而第三方代码更新迭代速度慢,所以我们将第三方代码(库,框架)进行抽离,这样可以充分利用浏览器的缓存来加载第三方库。
    • 按需加载:比如在使用 React-Router 的时候,当用户需要访问到某个路由的时候再去加载对应的组件,那么用户没有必要在一开始的时候就将所有的路由组件下载到本地。
    • 在多页面应用中,我们往往可以将公共模块进行抽离,比如 header, footer 等等,这样页面在进行跳转的时候这些公共模块因为存在于缓存里,就可以直接进行加载了,而不是再进行网络请求了。

    那么如何进行分隔打包,分模块进行加载。在webpack4之前,借助 webpack 内置插件:CommonsChunkPlugin可以实现分隔打包,深入理解 webpack 文件打包机制。在webpack4之后,借助内置SplitChunks即可轻松实现。webpack4 SplitChunks实现代码分隔详解

    转载于:https://juejin.im/post/5ce53a7f6fb9a07ede0b1a5c

    展开全文
  • 最近在看 webpack 如何做持久化缓存的内容,发现其中还是有一些坑点的,正好有时间就将它们整理总结一下,读完本文你大致能够明白: <ol><li>什么是持久化缓存,为什么做持久化缓存?...
  • <ol><li>webpack 单文件如何进行打包?</li><li>webpack 多文件如何进行代码切割?</li><li>webpack1 和 webpack2 在文件打包上有什么区别?</li><li>webpack2 如何做到 tree shaking?</li><li>...
  • 简单分析下需求,就是,项目A/B/C的内容是交叉的,有的页面不同,有的页面和组件是公用的,例如A项目多了个人中心及其里面所有内容(最全的一个项目,但是是放在微信中的,需要获取微信授权),B项目是通用版的项目(也...
  • 缓存的目的在于浏览器端能够缓存下资源文件,而不用花时间去服务器获取资源,降低网络流量,提高访问速度。缓存的问题在于,如何确保资源文件更新后,浏览器能够拿到最新的文件而不是缓存的过期文件。 除了通过...
  • 获取到的参数传入Webpack来打包。 当然你也可以从命令行(CLI)开始学习Webpack,以后你可能主要在生产模式下使用到它。 用法: <pre><code> js 方式1: // 全局模式安装webpack npm ...
  • <div><p>本篇主要介绍webpack的基本原理以及基于webpack搭建前端项目工程化解决方案的思路。 下篇(还没写)探讨下对于Node.js作为后端的项目工程化、模块化、前后端共享代码、自动化部署的做法。 关于...
  • 本文主要讲解了目前最流行的前端 webpack 工程化打包工具的内部打包原理和如何实现各个模块之间的依赖分析和代码注入,然后手把手教大家亲自实现一个简易的 webpack 打包工具,帮助大家学习和更深层次的...
  • 如何使用此存储库? 您可以通过轻松阅读内容。 它也可以在存储库的manuscript目录中找到。 请注意,存储库默认为本书的dev分支。 master包含最新版本的源。 每个版本都有标记,以便您轻松找到与您正在阅读的书的...
  • 通过前面几章的实战,我们已经顺利的构建项目,并且从API接口获取到数据并且渲染出来了。制作更多的页面,更复杂的应用,就是各位自己根据自己的项目去调整的事情了。 本章讲一下如何配置子路由,因为我们的项目不...
  • vue-cli是如何工作的

    2020-12-26 05:12:42
    <p>title: vue-cli是如何工作的 date: 2017-06-16 <p>vue-cli是Vue.js官方脚手架命令行工具,我们可以用它快速搭建Vue.js项目,vue-cli最主要的功能就是初始化项目,既可以使用官方模板,...
  • 需要注意的是, 读取的内容是模板的 <code>tempalte</code> 目录.</strong> metalsmith 会返回文件路径和文件内容相映射的对象, 这样会方便 metalsmith 的中间件对文件进行处理. 之后, <code>vue cli</code> 使用了三...
  • “异步的” setState 如何同步获取 state fetch拦截器的实现 js 异步发展史 手写源码系列 手写 Promise Promise asap curry 柯理化 debounce throttle ES5 array api forEach map filter reduce ...
  • 平台游戏JS Capstone ...这是一个如何列出使用软件所需的内容以及如何安装它们的示例。 npm npm install npm@latest -g 安装 在获取免费的API密钥 克隆仓库 git clone git@github.com:sanadwj/Diamond-Co
  • 欢迎关注我的公众号睿Talk,获取我最新的文章: 一、前言 我们开发用到的一些库都有自己特有的命令,如webpack,babel和jest等。通过给这些命令输入不同的参数,可以得到相应的功能。通过篇文章,你将学会如何一步步...
  • 如何使用此存储库? 您可以通过轻松阅读内容。 它也可以在存储库的manuscript目录中找到。 这本书是在master分支下开发的。 它包含最新开发版本的源。 每个版本都有标记,以便您轻松找到与您正在阅读的书的版本相...
  • motorcortex-plugin-starter ... 除了注释之外,您始终可以参考以获取有关如何实现插件的详细信息。 如何使用 一旦您确定了您将要执行的任务,并且一旦决定了需要实施的事件的类型,就可以直接从基本/空白实
  • 此外,webpack配置已更改为查看NODE_ENV环境变量,并根据提供的内容进行生产或开发构建。 您可以使用yarn dev在开发人员模式下运行服务器,从而提供更好的调试帮助和更快的编译时间,也可以使用yarn prod在生产中...
  • (在答案,为你推介获取正确信息的指南,也作为你披荆斩棘的引路人) In Answer, you can easily find friends who have been in the same predicament. all the people on the street (在答案,你可以轻易找到曾经历...
  • 如何运行 运行前请先安装nodejs clone项目到本地 git clone https://github.com/lybenson/bilibili-vue.git 前端运行 cd bilibili-vue npm install npm run dev 后端运行 cd bilibili-vue/bilibili-api npm install ...
  • 溢出隐藏的内容后面再添加几个字 --2019-10-22 文字超出省略号类型 --2019-10-08 Css3无缝滚动防抖 --2019-04-08 显示更多 css隐藏滚动条 --2019-04-10 日常页码样式问题 --2020-11-03 三大样式穿透 --...
  • 数据:获取与鉴权 数据展示:模板引擎 交互:事件与状态管理 组件交互:状态管理 用户交互:事件 客户端存储与模型的艺术 模型与存储 存储 模型的变化 如何优化前端应用性能 博客优化经验:速度优化 ...
  • 深入浅出React和Redux

    2018-04-21 09:01:51
    12.2 构建渲染动态内容服务器239 12.2.1 设置Node.js和Express240 12.2.2 热加载242 12.3 React同构246 12.3.1 React服务器端渲染HTML247 12.3.2 脱水和注水248 12.3.3 服务器端Redux Store249 12.3.4...

空空如也

空空如也

1 2 3
收藏数 45
精华内容 18
关键字:

如何获取webpack内容