zhangyuang/egg-react-ssr

关于分割vendor的模块问题导致代码异常的问题

Closed this issue · 9 comments

我在自己的项目中引入了quill.js和highlight.js,由于这个两个模块包体积是比较大的,所以我打算将他们打包的时候单独分离出来
于是在webpack.config.client.js 中添加了以下代码,然后我再次运行npm start时发现代码失效,无法生成编辑器

const optimization = {
  runtimeChunk: true,
  splitChunks: {
    chunks: 'all',
    name: false,
    cacheGroups: {
      vendors: {
        test: (module) => {
          return module.resource &&
            /\.js$/.test(module.resource) &&
            module.resource.match('node_modules')
        },
        name: 'vendor'
      },
      highlightJs: {
        name: 'highlight.js',
        test: (module) => {
          return /highlight.js/.test(module.context);
        },
        chunks: 'initial',
        priority: 13,
        enforce: true,
      },
      quill: {
        name: 'quill',
        test: (module) => {
          return /quill/.test(module.context);
        },
        chunks: 'initial',
        priority: 13,
        enforce: true,
      },
    }
  }
}

但是我去掉这个配置运行又是可以照常运行的,请问这个是为什么?
而且我运行了npm run analyze webpack的确将代码分割了
image

我用官方的例子做了可复现的demo,只需初始化官方脚手架和npm install highlight.js react-quill
然后将以下代码复制到page/index.js中即可

import React, { useState, useEffect, useRef } from 'react'
import { Link } from 'react-router-dom'
import hljs from 'highlight.js'
import './index.less'
import 'react-quill/dist/quill.snow.css'
import 'highlight.js/styles/gruvbox-dark.css'
const ReactQuill = __isBrowser__ ? require('react-quill') : null

const modules = {
  toolbar: {
    container: [
      [{ 'header': [1, 2, 3, 4, false] }],
      ['bold', 'italic', 'underline', 'strike', 'blockquote', 'code-block'],
      [{ 'list': 'ordered' }, { 'list': 'bullet' }, { 'indent': '-1' }, { 'indent': '+1' }],
      ['link', 'image'],
    ],
  },
  syntax: {
    highlight: text => hljs.highlightAuto(text).value,
  },
}
let quillRef
function Page(props) {
  const [value, setValue] = useState('')
  quillRef = useRef()
  const onChangeValue = (params) => {
    setValue(params)
  }
  return (
    <div className='normal'>
      <div className='welcome' />
      <div>
        {
          __isBrowser__ ?
            <>
              <ReactQuill
                ref={quillRef}
                theme="snow"
                modules={modules}
                value={value}
                placeholder="写一篇文章..."
                style={{ maxHeight: 'calc(100vh - 172px)', width: '100%', height: "100%" }}
                onChange={onChangeValue} />
            </>

            : null
        }
      </div>
      <ul className='list'>
        {
          props.news && props.news.map(item => (
            <li key={item.id}>
              <div>文章标题: {item.title}</div>
              <div className='toDetail'><Link to={`/news/${item.id}`}>点击查看详情</Link></div>
            </li>
          ))
        }
      </ul>
      
    </div>
  )
}

Page.getInitialProps = async (ctx) => {
  // ssr渲染模式只在服务端通过Node获取数据,csr渲染模式只在客户端通过http请求获取数据,getInitialProps方法在整个页面生命周期只会执行一次
  return __isBrowser__ ? (await window.fetch('/api/getIndexData')).json() : ctx.service.api.index()
}

export default Page

还是在首屏加载的话你这个分割没有意义

这个只是我做的一个demo方便看而已,你可以将其移到news,我真实业务也不是首屏的,我只想问下为什么分割了却在npm start时没有加载对应的chunk模块,而且也没有报错就是相关代码不生效了,无法生成编辑器了

injectScript

image
请问是如图所更改吗?我改了之后的确是正确加载了对应chunk,但是页面表现却跟之前的不一样?请问这个是业务问题还是我别得地方没有改全?

要先加载runtime。而且你这个分块确实没什么意义你如果想要做代码分割的话应该去看ssr-with-loadable的例子 发自我的iPhone

------------------ 原始邮件 ------------------ 发件人: Dseekers <notifications@github.com> 发送时间: 2020年5月29日 18:50 收件人: ykfe/egg-react-ssr <egg-react-ssr@noreply.github.com> 抄送: LeonCheung <569105585@qq.com>, Comment <comment@noreply.github.com> 主题: 回复:[ykfe/egg-react-ssr] 关于分割vendor的模块问题导致代码异常的问题 (#169) injectScript 请问是如图所更改吗?我改了之后的确是正确加载了对应chunk,但是页面表现却跟之前的不一样?请问这个是业务问题还是我别得地方没有改全? — You are receiving this because you commented. Reply to this email directly, view it on GitHub, or unsubscribe.

我发现好像是没有加对应的css所以有点怪,请问有关于ssr-with-loadable和这个框架结合的文章或者例子吗?

我还有个问题,就是将我看webpack打包出来的全是没有hash值的静态资源,那我每次版本更新的话岂不是会有http缓存?而且我习惯于将这些这些js和css传到静态cdn上去,这些文件没有hash值如何区分版本,我看之前的issue有相关的内容,你有提到过用文件夹做区分?请问具体如何做吗?

@Dseekers 默认不使用hash。我建议你可以直接用https://github.com/ykfe/ssr 这个框架生产环境支持hash。细节都给你底层打平了