Next.js v4.1.4 文档中文翻译

最近想稍稍看下 ReactSSR框架 Next.js,因为不想看二手资料,
所以自己跑到 Github上看,Next.js的文档是英文的,看倒是大概也能看得懂,
但有些地方不太确定,而且英文看着毕竟不太爽你懂得,所以在网上搜了几圈发现好像好像还没有中文翻译,想着长痛不如短痛,
索性一边看一边翻译,自己翻译的东西自己看得也爽,不过毕竟能力有限,有些地方我也不知道该怎么翻译才好,所以翻译得不太通畅,
或者有几句干脆不翻译了。

so,各位若是觉得我哪点翻译得不太准确,或者对于那几句我没翻译的地方有更好的见解,欢迎提出~

以下是全文翻译的 Next.js的 README.md文件,版本是 v4.1.4,除了翻译原文之外,还加了一点个人小小见解。

另外,本文翻译已经放到了我的 github上,想要更好的阅读体验可以去看下,别忘了 star哦~


Next.js v4.1.4 文档中文翻译_第1张图片

Next.js是一个用于React应用的极简的服务端渲染框架。

请访问 learnnextjs.com 以获取更多详细内容.


  • 如何使用
    • 安装
    • 代码自动分割
    • CSS
    • 嵌入式样式(Built-in-CSS)
    • 内联式样式(CSS-in-JS)
    • 静态文件服务 (例如: images)
    • 自定义 头部元素
    • 数据获取及组件生命周期
    • 路由
    • 命令式路由
      • 路由事件
      • 浅层路由(Shallow Routing)
    • 使用高阶函数(HOC)
    • 预获取页面(Prefetching Pages)
    • 通过 组件
    • 通过命令的方式
    • 自定义服务器和路由
    • 异步导入(Dynamic Import)
    • 自定义
    • 自定义错误处理
    • 自定义配置
    • 自定义 webpack 配置
    • 自定义 babel 配置
    • CDN支持
  • 项目部署
  • 导出静态 HTML 页面面
  • 相关技巧
  • FAQ
  • contributing
  • authors

如何使用

安装

安装方法:

npm install --save next react react-dom

Next.js 4 只支持 React 16.

由于 React 16React 15 的工作方式以及使用方法不尽相同,所以我们不得不移除了对 React 15 的支持

在你的 package.json文件中添加如下代码:

{
  "scripts": {
    "dev": "next",
    "build": "next build",
    "start": "next start"
  }
}

接下来,大部分事情都交由文件系统来处理。每个 .js 文件都变成了一个自动处理和渲染的路由。

在项目中新建 ./pages/index.js

export default () => 
Welcome to next.js!

然后,在控制台输入 npm run dev命令,打开 http://localhost:3000即可看到程序已经运行,你当然也可以使用其他的端口号,可以使用这条命令:npm run dev -- -p

目前为止,我们已经介绍了:

  • 自动编译和打包 (使用 webpackbabel)
  • 代码热更新
  • ./pages目录作为页面渲染目录的的服务器端渲染
  • 静态文件服务(./static/ 被自动定位到 /static/)

想要亲自试试这些到底有多简单, check out sample app - nextgram

代码自动分割

你所声明的每个 import命令所导入的文件会只会与相关页面进行绑定并提供服务,也就是说,页面不会加载不需要的代码。

import cowsay from 'cowsay-browser'

export default () =>
  
    {cowsay.say({ text: 'hi there!' })}
  

CSS

嵌入式样式 Built-in-CSS

Examples

  • Basic css

我们提供 style-jsx来支持局部独立作用域的 CSS(scope CSS),目的是提供一种类似于 Web组件的 shadow CSS,不过,后者(即shadow CSS)并不支持服务器端渲染(scope CSS是支持的)。

export default () =>
  <div>
    Hello world
    <p>scoped!p>
    <style jsx>{`
      p {
        color: blue;
      }
      div {
        background: red;
      }
      @media (max-width: 600px) {
        div {
          background: blue;
        }
      }
    `}style>
    <style global jsx>{`
      body {
        background: black;
      }
    `}style>
  div>

更多示例可见 styled-jsx documentation

译者注:
1. scope CSS的作用范围,如果添加了 jsx属性,则是不包括子组件的当前组件;如果添加了 globaljsx属性,则是包括了子组件在内的当前组件;如果没添加任何属性,则作用与 添加了 globaljsx的作用类似,只不过 next不会对其进行额外的提取与优化打包
2. scope CSS的实现原理,其实就是在编译好的代码的对应元素上,添加一个以 jsx开头的类名(class),然后将对应的样式代码提取到此类名下

内联式样式 CSS-in-JS

Examples

  • Styled components
  • Styletron
  • Glamor
  • Glamorous
  • Cxs
  • Aphrodite
  • Fela

几乎可以使用所有的内联样式解决方案,最简单一种如下:

export default () => 

color: 'red' }}>hi there

为了使用更多复杂的 CSS-in-JS 内联样式方案,你可能不得不在服务器端渲染的时候强制样式刷新。我们通过允许自定义包裹着每个页面的 组件的方式来解决此问题。

静态文件服务

在你的项目的根目录新建 static 文件夹,然后你就可以在你的代码通过 /static/ 开头的路径来引用此文件夹下的文件:

export default () => "/static/my-image.png" />

自定义 头部元素

Examples

  • Head elements
  • Layout component

我们暴露了一个用于将元素追加到 中的组件。

import Head from 'next/head'

export default () =>
  <div>
    <Head>
      <title>My page titletitle>
      <meta name="viewport" content="initial-scale=1.0, width=device-width" />
    Head>
    <p>Hello world!p>
  div>

注意:当组件卸载的时候,组件内定义的 将会被清空,所以请确保每个页面都在其各自的 内声明了其所有需要的内容,而不是假定这些东西已经在其他页面中添加过了。

译者注:
1. next 框架自带 标签,作为当前页面的 ,如果在组件内自定义了 ,则自定义 内的元素(例如 </code>、<code><meta></code>等)将会被追加到框架自带的 <code><head></code>标签中 <br> 2. 每个组件自定义的 <code><Head></code>内容只会应用在各自的页面上,子组件内定义的 <code><Head></code>也会追加到当前页面的 <code><head></code>内,如果有重复定义的标签或属性,则子组件覆盖父组件,位于文档更后面的组件覆盖更前面的组件。</p> </blockquote> <h3 id="数据获取及组件生命周期">数据获取及组件生命周期</h3> <p> <b>Examples</b> </p> <ul> <li>Data fetch</li> </ul> <p></p> <p>你可以通过导出一个基于 <code>React.Component</code>的组件来获取状态(<code>state</code>)、生命周期或者初始数据(而不是一个无状态函数(<code>stateless</code>),就像上面的一段代码)</p> <pre class="prettyprint"><code class="language-jsx hljs axapta">import React from <span class="hljs-string">'react'</span> export <span class="hljs-keyword">default</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-inheritance"><span class="hljs-keyword">extends</span></span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span> {</span> <span class="hljs-keyword">static</span> async getInitialProps({ req }) { const userAgent = req ? req.headers[<span class="hljs-string">'user-agent'</span>] : navigator.userAgent <span class="hljs-keyword">return</span> { userAgent } } render() { <span class="hljs-keyword">return</span> ( <<span class="hljs-keyword">div</span>> Hello World {<span class="hljs-keyword">this</span>.props.userAgent} </<span class="hljs-keyword">div</span>> ) } }</code></pre> <p>你可能已经注意到了,当加载页面获取数据的时候,我们使用了一个异步(<code>async</code>)的静态方法 <code>getInitialProps</code>。此静态方法能够获取所有的数据,并将其解析成一个 <code>JavaScript</code>对象,然后将其作为属性附加到 <code>props</code>对象上。</p> <p>当初始化页面的时候,<code>getInitialProps</code>只会在服务器端执行,而当通过 <code>Link</code>组件或者使用命令路由 <code>API</code>来将页面导航到另外一个路由的时候,此方法就只会在客户端执行。</p> <p><em>注意:<code>getInitialProps</code> <strong>不能</strong> 在子组件上使用,只能应用于当前页面的顶层组件。</em></p> <p><br></p> <blockquote> <p>如果你在 <code>getInitialProps</code> 中引入了一些只能在服务器端使用的模块(例如一些 <code>node.js</code>的核心模块),请确保通过正确的方式来导入它们 import them properly,否则的话,那很可能会拖慢应用的速度。</p> </blockquote> <p><br></p> <p>你也可以为无状态(<code>stateless</code>)组件自定义 <code>getInitialProps</code>生命周期方法:</p> <pre class="prettyprint"><code class="language-jsx hljs coffeescript"><span class="hljs-reserved">const</span> <span class="hljs-function"><span class="hljs-title">Page</span> = <span class="hljs-params">({ stars })</span> =></span> <div> Next <span class="hljs-attribute">stars</span>: {stars} </div> Page.getInitialProps = async <span class="hljs-function"><span class="hljs-params">({ req })</span> =></span> { <span class="hljs-reserved">const</span> res = await fetch(<span class="hljs-string">'https://api.github.com/repos/zeit/next.js'</span>) <span class="hljs-reserved">const</span> json = await res.json() <span class="hljs-keyword">return</span> { <span class="hljs-attribute">stars</span>: json.stargazers_count } } <span class="hljs-reserved">export</span> <span class="hljs-reserved">default</span> Page</code></pre> <p><code>getInitialProps</code> 接收的上下文对象包含以下属性: <br> - <code>pathname</code> - <code>URL</code>的 <code>path</code>部分 <br> - <code>query</code> - <code>URL</code>的 <code>query string</code>部分,并且其已经被解析成了一个对象 <br> - <code>asPath</code> - 在浏览器上展示的实际路径(包括 <code>query</code>字符串) <br> - <code>req</code> - <code>HTTP request</code> 对象 (只存在于服务器端) <br> - <code>res</code> - <code>HTTP response</code> 对象 (只存在于服务器端) <br> - <code>jsonPageRes</code> - 获取的响应数据对象 Fetch Response (只存在于客户端) <br> - <code>err</code> - 渲染时发生错误抛出的错误对象</p> <blockquote> <p>译者注: <br> 基于 <code>getInitialProps</code>在服务器端和客户端的不同表现,例如 <code>req</code>的存在与否,可以通过此来区分服务器端和客户端。</p> </blockquote> <h3 id="路由">路由</h3> <h4 id="link"><code><Link></code></h4> <p> <b>Examples</b> </p> <ul> <li>Hello World</li> </ul> <p></p> <p>可以通过 <code><Link></code> 组件来实现客户端在两个路由间的切换功能,例如下面两个页面:</p> <pre class="prettyprint"><code class="language-jsx hljs livecodeserver">// pages/index.js import Link <span class="hljs-built_in">from</span> <span class="hljs-string">'next/link'</span> export default () => <<span class="hljs-operator">div</span>> Click{<span class="hljs-string">' '</span>} <Link href=<span class="hljs-string">"/about"</span>> <<span class="hljs-operator">a</span>>here</<span class="hljs-operator">a</span>> </Link>{<span class="hljs-string">' '</span>} <span class="hljs-built_in">to</span> <span class="hljs-built_in">read</span> more </<span class="hljs-operator">div</span>></code></pre> <pre class="prettyprint"><code class="language-jsx hljs coffeescript"><span class="hljs-regexp">//</span> pages/about.js <span class="hljs-reserved">export</span> <span class="hljs-reserved">default</span> <span class="hljs-function"><span class="hljs-params">()</span> =></span> <p>Welcome to About!</p></code></pre> <p><em>注意:可以使用 <code><Link prefetch></code> 来让页面在后台同时获取和预加载,以获得最佳的页面加载性能</em></p> <p>客户端路由行为与浏览器完全相同:</p> <ol> <li>获取组件</li> <li>如果组件定义了 <code>getInitialProps</code>,那么进行数据的获取,如果抛出异常,则将渲染<code>_error.js</code></li> <li>在步骤<code>1</code>和步骤<code>2</code>完成后,<code>pushState</code>开始执行,接着新组件将会被渲染</li> </ol> <p>每一个顶层组件都会接收到一个 <code>url</code>属性,其包括了以下 <code>API</code>:</p> <ul> <li><code>pathname</code> - 不包括 <code>query</code>字符串在内的当前链接地址的 <code>path</code>字符串(即<code>pathname</code>)</li> <li><code>query</code> - 当前链接地址的 <code>query</code>字符串,已经被解析为对象,默认为 <code>{}</code></li> <li><code>asPath</code> - 在浏览器地址栏显示的当前页面的实际地址(包括 <code>query</code>字符串)</li> <li><code>push(url, as=url)</code> - 通过 <code>pushState</code>来跳转路由到给定的 <code>url</code></li> <li><code>replace(url, as=url)</code> - 通过 <code>replaceState</code>来将当前路由替换到给定的路由地址 <code>url</code>上</li> </ul> <p><code>push</code> 以及 <code>replace</code>的第二个参数 <code>as</code>提供了额外的配置项,当你在服务器上配置了自定义路由的话,那么此参数就会发挥作用。</p> <blockquote> <p>译者注1: <br> 上面那句话的意思是,<code>as</code>可以根据服务器端路由的配置作出相应的 路由改变,例如,在服务器端,你自定义规定当获取 <code>/a</code>的 <code>path</code>请求的时候,返回一个位于 <code>/b</code>目录下的页面,则为了配合服务器端的这种指定,你可以这么定义 <code><Link/></code>组件: <code><Link href='/b' as='/a'><a>a</a></Link></code>。 <br> 这种做法有一个好处,那就是尽管你将 <code>/a</code>请求指定到了 <code>/b</code>页面,但是因为<code>as</code>的值为 <code>/a</code>,所以编译后的 <code>DOM</code>元素显示的链接的 <code>href</code>值为 <code>/a</code>,但是当真正点击链接时,响应的真正页面还是 <code>/b</code></p> <p>译者注2: <br> <code><Link></code>组件主要用于路由跳转功能,其可以接收一个必须的子元素(<code>DOM</code>标签或者纯文字等) <br> 1. 如果添加的子元素是 <code>DOM</code>元素,则 <code>Link</code>会为此子元素赋予路由跳转功能; <br> 2. 如果添加的元素是纯文字,则 <code><Link></code>默认转化为 <code>a</code>标签,包裹在此文字外部(即作为文字的父元素),如果当前组件有 <code>jsx</code>属性的 <code>scope CSS</code>,这个 <code>a</code>标签是不会受此 <code>scope CSS</code>影响的,也就是说,不会加上以 <code>jsx</code>开头的类名。<br> 需要注意的是,直接添加纯文字作为子元素的做法如今已经不被赞成了(<strong>deprecated</strong>)。</p> </blockquote> <h5 id="url-对象">URL 对象</h5> <p> <b>Examples</b> </p> <ul> <li>With URL Object Routing</li> </ul> <p></p> <p><code><Link></code>组件可以接收一个 <code>URL</code>对象,此 <code>URL</code>对象将会被自动格式化为 <code>URL</code>字符串。</p> <pre class="prettyprint"><code class="language-jsx hljs handlebars"><span class="xml">// pages/index.js import Link from 'next/link' export default () => <span class="hljs-tag"><<span class="hljs-title">div</span>></span> Click{' '} <span class="hljs-tag"><<span class="hljs-title">Link</span> <span class="hljs-attribute">href</span>=</span></span><span class="hljs-expression">{{ <span class="hljs-variable">pathname</span>: '<span class="hljs-end-block">/about</span>', <span class="hljs-variable">query</span>: { <span class="hljs-variable">name</span>: '<span class="hljs-variable">Zeit</span>' } }}</span><span class="xml"><span class="hljs-tag">></span> <span class="hljs-tag"><<span class="hljs-title">a</span>></span>here<span class="hljs-tag"></<span class="hljs-title">a</span>></span> <span class="hljs-tag"></<span class="hljs-title">Link</span>></span>{' '} to read more <span class="hljs-tag"></<span class="hljs-title">div</span>></span></span></code></pre> <p>上述代码中 <code><Link></code>组件的将会根据 <code>href</code>属性的对象值生成一个 <code>/about?name=Zeit</code>的 <code>URL</code>字符串,你也可以在此 <code>URL</code>对象中使用任何已经在 Node.js URL module documentation 中定义好了的属性来配置路由。</p> <h5 id="替换-replace而非追加push路由-url">替换 (<code>replace</code>)而非追加(<code>push</code>)路由 <code>url</code></h5> <p><code><Link></code>组件默认将新的 <code>URL</code>追加 (<code>push</code>)到路由栈中,但你可以使用 <code>replace</code>属性来避免此追加动作(直接替换掉当前路由)。</p> <pre class="prettyprint"><code class="language-jsx hljs livecodeserver">// pages/index.js import Link <span class="hljs-built_in">from</span> <span class="hljs-string">'next/link'</span> export default () => <<span class="hljs-operator">div</span>> Click{<span class="hljs-string">' '</span>} <Link href=<span class="hljs-string">"/about"</span> <span class="hljs-built_in">replace</span>> <<span class="hljs-operator">a</span>>here</<span class="hljs-operator">a</span>> </Link>{<span class="hljs-string">' '</span>} <span class="hljs-built_in">to</span> <span class="hljs-built_in">read</span> more </<span class="hljs-operator">div</span>></code></pre> <h5 id="让组件支持-onclick事件">让组件支持 <code>onClick</code>事件</h5> <p><code><Link></code> supports any component that supports the <code>onClick</code> event. In case you don’t provide an <code><a></code> tag, it will only add the <code>onClick</code> event handler and won’t pass the <code>href</code> property. <br> <code><Link></code>标签支持所有支持 <code>onClick</code>事件的组件(即只要某组件或者元素标签支持 <code>onClick</code>事件,则 <code><Link></code>就能够为其提供跳转路由的功能)。如果你没有给 <code><Link></code>标签添加一个 <code><a></code>标签的子元素的话,那么它只会执行给定的 <code>onClick</code>事件,而不是执行跳转路由的动作。</p> <pre class="prettyprint"><code class="language-jsx hljs coffeescript"><span class="hljs-regexp">//</span> pages/index.js <span class="hljs-reserved">import</span> Link from <span class="hljs-string">'next/link'</span> <span class="hljs-reserved">export</span> <span class="hljs-reserved">default</span> <span class="hljs-function"><span class="hljs-params">()</span> =></span> <div> Click{<span class="hljs-string">' '</span>} <Link href=<span class="hljs-string">"/about"</span>> <img src=<span class="hljs-string">"/static/image.png"</span> /> </Link> </div></code></pre> <h5 id="将-link的-href暴露给其子元素child">将 <code><Link></code>的 <code>href</code>暴露给其子元素(<code>child</code>)</h5> <p>如果 <code><Link></code>的子元素是一个 <code><a></code>标签并且没有指定 <code>href</code>属性的话,那么我们会自动指定此属性(与 <code><Link></code>的 <code>herf</code>相同)以避免重复工作,然而有时候,你可能想要通过一个被包裹在某个容器(例如组件)内的 <code><a></code>标签来实现跳转功能,但是 <code>Link</code>并不认为那是一个超链接,因此,就不会把它的 <code>href</code>属性传递给子元素,为了避免此问题,你应该给 <code>Link</code>附加一个 <code>passHref</code>属性,强制让 <code>Link</code>将其 <code>href</code>属性传递给它的子元素。</p> <pre class="prettyprint"><code class="language-jsx hljs coffeescript"><span class="hljs-reserved">import</span> Link from <span class="hljs-string">'next/link'</span> <span class="hljs-reserved">import</span> Unexpected_A from <span class="hljs-string">'third-library'</span> <span class="hljs-reserved">export</span> <span class="hljs-reserved">default</span> <span class="hljs-function"><span class="hljs-params">({ href, name })</span> =></span> <Link href={href} passHref> <Unexpected_A> {name} </Unexpected_A> </Link></code></pre> <h4 id="命令式路由">命令式路由</h4> <p> <b>Examples</b> </p> <ul> <li>Basic routing</li> <li>With a page loading indicator</li> </ul> <p></p> <p>你可以使用 <code>next/router</code>来实现客户端侧的页面切换</p> <pre class="prettyprint"><code class="language-jsx hljs coffeescript"><span class="hljs-reserved">import</span> Router from <span class="hljs-string">'next/router'</span> <span class="hljs-reserved">export</span> <span class="hljs-reserved">default</span> <span class="hljs-function"><span class="hljs-params">()</span> =></span> <div> Click <span onClick={<span class="hljs-function"><span class="hljs-params">()</span> =></span> Router.push(<span class="hljs-string">'/about'</span>)}>here</span> to read more </div></code></pre> <p>上述代码中的 <code>Router</code>对象拥有以下 <code>API</code>:</p> <ul> <li><code>route</code> - 当前路由字符串</li> <li><code>pathname</code> - 不包括查询字符串(<code>query string</code>)在内的当前路由的 <code>path</code>(也就是 <code>pathname</code>)</li> <li><code>query</code> - <code>Object</code> with the parsed query string. Defaults to <code>{}</code></li> <li><code>asPath</code> - 在浏览器地址栏显示的当前页面的实际地址(包括 <code>query</code>字符串)</li> <li><code>push(url, as=url)</code> - 通过 <code>pushState</code>来跳转路由到给定的 <code>url</code></li> <li><code>replace(url, as=url)</code> - 通过 <code>replaceState</code>来将当前路由替换到给定的路由地址 <code>url</code>上</li> </ul> <p><code>push</code> 以及 <code>replace</code>的第二个参数 <code>as</code>提供了额外的配置项,当你在服务器上配置了自定义路由的话,那么此参数就会发挥作用。</p> <p><em>为了使用编程的方式而不是触发导航和组件获取的方式来切换路由,可以在组件内部使用 <code>props.url.push</code> 和 <code>props.url.replace</code></em></p> <blockquote> <p>译者注: <br> 除非特殊需要,否则在组件内部不赞成(<strong>deprecated</strong>)使用 <code>props.url.push</code> 和 <code>props.url.replace</code>,而是建议使用 <code>next/router</code>的相关 <code>API</code>。</p> </blockquote> <h5 id="url-对象-1">URL 对象</h5> <p>命令式路由 (<code>next/router</code>)所接收的 <code>URL</code>对象与 <code><Link></code>的 <code>URL</code>对象很类似,你可以使用相同的方式来<code>push</code> 和 <code>replace</code>路由<code>URL</code></p> <pre class="prettyprint"><code class="language-jsx hljs coffeescript"><span class="hljs-reserved">import</span> Router from <span class="hljs-string">'next/router'</span> <span class="hljs-reserved">const</span> <span class="hljs-function"><span class="hljs-title">handler</span> = <span class="hljs-params">()</span> =></span> Router.push({ <span class="hljs-attribute">pathname</span>: <span class="hljs-string">'/about'</span>, <span class="hljs-attribute">query</span>: { <span class="hljs-attribute">name</span>: <span class="hljs-string">'Zeit'</span> } }) <span class="hljs-reserved">export</span> <span class="hljs-reserved">default</span> <span class="hljs-function"><span class="hljs-params">()</span> =></span> <div> Click <span onClick={handler}>here</span> to read more </div></code></pre> <p>命令式路由 (<code>next/router</code>)的 <code>URL</code>对象的属性及其参数的使用方法和 <code><Link></code>组件的完全一样。</p> <h5 id="路由事件">路由事件</h5> <p>你还可以监听到与 <code>Router</code>相关的一些事件。</p> <p>以下是你所能够监听的 <code>Router</code>事件:</p> <ul> <li><code>routeChangeStart(url)</code> - 当路由刚开始切换的时候触发</li> <li><code>routeChangeComplete(url)</code> - 当路由切换完成时触发</li> <li><code>routeChangeError(err, url)</code> - 当路由切换发生错误时触发</li> <li><code>beforeHistoryChange(url)</code> - 在改变浏览器 <code>history</code>之前触发</li> <li><code>appUpdated(nextRoute)</code> - 当切换页面的时候,应用版本刚好更新的时触发(例如在部署期间切换路由)</li> </ul> <blockquote> <p>Here <code>url</code> is the URL shown in the browser. If you call <code>Router.push(url, as)</code> (or similar), then the value of <code>url</code> will be <code>as</code>. <br> 上面 <code>API</code>中的 <code>url</code>参数指的是浏览器地址栏显示的链接地址,如果你使用 <code>Router.push(url, as)</code>(或者类似的方法)来改变路由,则此值就将是 <code>as</code>的值</p> </blockquote> <p>下面是一段如何正确地监听路由事件 <code>routeChangeStart</code>的示例代码:</p> <pre class="prettyprint"><code class="language-js hljs ">Router.onRouteChangeStart = url => { console.log(<span class="hljs-string">'App is changing to: '</span>, url) }</code></pre> <p>如果你不想继续监听此事件了,那么你也可以很轻松地卸载掉此监听事件,就像下面这样:</p> <pre class="prettyprint"><code class="language-js hljs ">Router.onRouteChangeStart = <span class="hljs-literal">null</span></code></pre> <p>如果某个路由加载被取消掉了(例如连续快速地单击两个链接),<code>routeChangeError</code> 将会被执行。此方法的第一个参数 <code>err</code>对象中将包括一个值为 <code>true</code>的 <code>cancelled</code>属性。</p> <pre class="prettyprint"><code class="language-js hljs ">Router.onRouteChangeError = (err, url) => { <span class="hljs-keyword">if</span> (err.cancelled) { console.log(`Route to ${url} was cancelled!`) } }</code></pre> <p>如果你在一次项目新部署的过程中改变了路由,那么我们就无法在客户端对应用进行导航,必须要进行一次完整的导航动作(译者注:意思是无法像正常那样通过 <code>PWA</code>的方式进行导航),我们已经自动帮你做了这些事。 <br> 不过,你也可以通过 <code>Route.onAppUpdated</code>事件对此进行自定义操作,就像下面这样:</p> <pre class="prettyprint"><code class="language-js hljs ">Router.onAppUpdated = nextUrl => { <span class="hljs-comment">// persist the local state</span> location.href = nextUrl }</code></pre> <blockquote> <p>译者注:<br> 一般情况下,上述路由事件的发生顺序如下: <br> 1. <code>routeChangeStart</code> <br> 2. <code>beforeHistoryChange</code> <br> 3. <code>routeChangeComplete</code></p> </blockquote> <h5 id="浅层路由">浅层路由</h5> <p> <b>Examples</b> </p> <ul> <li>Shallow Routing</li> </ul> <p></p> <p>浅层路由(<code>Shallow routing</code>)允许你在不触发 <code>getInitialProps</code>的情况下改变路由(<code>URL</code>),你可以通过要加载页面的 <code>url</code>来获取更新后的 <code>pathname</code> 和 <code>query</code>,这样就不会丢失路由状态(<code>state</code>)了。</p> <p>你可以通过调用 <code>Router.push</code> 或 <code>Router.replace</code>,并给它们加上 <code>shallow: true</code>的配置参数来实现此功能,下面是一个使用示例:</p> <pre class="prettyprint"><code class="language-js hljs "><span class="hljs-comment">// Current URL is "/"</span> <span class="hljs-keyword">const</span> href = <span class="hljs-string">'/?counter=10'</span> <span class="hljs-keyword">const</span> as = href Router.push(href, as, { shallow: <span class="hljs-literal">true</span> })</code></pre> <p>现在,<code>URL</code>已经被更新到了 <code>/?counter=10</code>,你可以在组件内部通过 <code>this.props.url</code>来获取此 <code>URL</code></p> <p>你可以在 <code>componentWillReceiveProps</code>钩子函数中获取到 <code>URL</code>的变化,就像下面这样:</p> <pre class="prettyprint"><code class="language-js hljs ">componentWillReceiveProps(nextProps) { <span class="hljs-keyword">const</span> { pathname, query } = nextProps.url <span class="hljs-comment">// fetch data based on the new query</span> }</code></pre> <blockquote> <p>注意:</p> <p>浅层路由只会在某些页面上起作用,例如,我们可以假定存在另外一个名为 <code>about</code>的页面,然后执行下面这行代码:</p> <pre class="prettyprint"><code class="language-js hljs ">Router.push(<span class="hljs-string">'/about?counter=10'</span>, <span class="hljs-string">'/about?counter=10'</span>, { shallow: <span class="hljs-literal">true</span> })</code></pre> <p>因为这是一个新的页面(<code>/about?counter=10</code>),所以即使我们已经声明了只执行浅层路由,但当前页面仍然会被卸载掉(<code>unload</code>),然后加载这个新的页面并调用 <code>getInitialProps</code>方法</p> </blockquote> <h4 id="使用高阶函数-hoc">使用高阶函数 HOC</h4> <p> <b>Examples</b> </p> <ul> <li>Using the `withRouter` utility</li> </ul> <p></p> <p>如果你想在应用的任何组件都能获取到 <code>router</code>对象,那么你可以使用 <code>withRouter</code>高阶函数,下面是一个使用此高阶函数的示例:</p> <pre class="prettyprint"><code class="language-jsx hljs coffeescript"><span class="hljs-reserved">import</span> { withRouter } from <span class="hljs-string">'next/router'</span> <span class="hljs-reserved">const</span> <span class="hljs-function"><span class="hljs-title">ActiveLink</span> = <span class="hljs-params">({ children, router, href })</span> =></span> { <span class="hljs-reserved">const</span> style = { <span class="hljs-attribute">marginRight</span>: <span class="hljs-number">10</span>, <span class="hljs-attribute">color</span>: router.pathname === href? <span class="hljs-string">'red'</span> : <span class="hljs-string">'black'</span> } <span class="hljs-reserved">const</span> <span class="hljs-function"><span class="hljs-title">handleClick</span> = <span class="hljs-params">(e)</span> =></span> { e.preventDefault() router.push(href) } <span class="hljs-keyword">return</span> ( <a href={href} onClick={handleClick} style={style}> {children} </a> ) } <span class="hljs-reserved">export</span> <span class="hljs-reserved">default</span> withRouter(ActiveLink)</code></pre> <p>上述代码中的 <code>router</code>对象拥有和 <code>next/router</code> 相同的 <code>API</code>。</p> <h3 id="预获取页面-prefetching-pages">预获取页面 Prefetching Pages</h3> <p>(下面就是一个小例子)</p> <p> <b>Examples</b> </p> <ul> <li>Prefetching</li> </ul> <p></p> <p><code>Next.js</code>自带允许你预获取(<code>prefetch</code>)页面的 <code>API</code></p> <p>因为 <code>Next.js</code>在服务器端渲染页面,所以应用的所有将来可能发生交互的相关链接路径可以在瞬间完成交互,事实上 <code>Next.js</code>可以通过预下载功能来达到一个绝佳的加载性能。[更多详细可见](Read more.)</p> <blockquote> <p>由于 <code>Next.js</code>只会预加载 <code>JS</code>代码,所以在页面加载的时候,你可以还需要花点时间来等待数据的获取。</p> </blockquote> <h4 id="通过-link-组件">通过 <code><Link></code> 组件</h4> <p>你可以为任何一个 <code><Link></code>组件添加 <code>prefetch</code>属性,<code>Next.js</code>将会在后台预加载这些页面。</p> <pre class="prettyprint"><code class="language-jsx hljs xml">import Link from 'next/link' // example header component export default () => <span class="hljs-tag"><<span class="hljs-title">nav</span>></span> <span class="hljs-tag"><<span class="hljs-title">ul</span>></span> <span class="hljs-tag"><<span class="hljs-title">li</span>></span> <span class="hljs-tag"><<span class="hljs-title">Link</span> <span class="hljs-attribute">prefetch</span> <span class="hljs-attribute">href</span>=<span class="hljs-value">"/"</span>></span> <span class="hljs-tag"><<span class="hljs-title">a</span>></span>Home<span class="hljs-tag"></<span class="hljs-title">a</span>></span> <span class="hljs-tag"></<span class="hljs-title">Link</span>></span> <span class="hljs-tag"></<span class="hljs-title">li</span>></span> <span class="hljs-tag"><<span class="hljs-title">li</span>></span> <span class="hljs-tag"><<span class="hljs-title">Link</span> <span class="hljs-attribute">prefetch</span> <span class="hljs-attribute">href</span>=<span class="hljs-value">"/about"</span>></span> <span class="hljs-tag"><<span class="hljs-title">a</span>></span>About<span class="hljs-tag"></<span class="hljs-title">a</span>></span> <span class="hljs-tag"></<span class="hljs-title">Link</span>></span> <span class="hljs-tag"></<span class="hljs-title">li</span>></span> <span class="hljs-tag"><<span class="hljs-title">li</span>></span> <span class="hljs-tag"><<span class="hljs-title">Link</span> <span class="hljs-attribute">prefetch</span> <span class="hljs-attribute">href</span>=<span class="hljs-value">"/contact"</span>></span> <span class="hljs-tag"><<span class="hljs-title">a</span>></span>Contact<span class="hljs-tag"></<span class="hljs-title">a</span>></span> <span class="hljs-tag"></<span class="hljs-title">Link</span>></span> <span class="hljs-tag"></<span class="hljs-title">li</span>></span> <span class="hljs-tag"></<span class="hljs-title">ul</span>></span> <span class="hljs-tag"></<span class="hljs-title">nav</span>></span></code></pre> <h4 id="通过命令的方式">通过命令的方式</h4> <p>大部分预获取功能都需要通过 <code><Link></code>组件来指定链接地址,但是我们还暴露了一个命令式的 <code>API</code>以方便更加复杂的场景:</p> <pre class="prettyprint"><code class="language-jsx hljs coffeescript"><span class="hljs-reserved">import</span> Router from <span class="hljs-string">'next/router'</span> <span class="hljs-reserved">export</span> <span class="hljs-reserved">default</span> <span class="hljs-function"><span class="hljs-params">({ url })</span> =></span> <div> <a onClick={<span class="hljs-function"><span class="hljs-params">()</span> =></span> setTimeout<span class="hljs-function"><span class="hljs-params">(() => url.pushTo(<span class="hljs-string">'/dynamic'</span>), <span class="hljs-number">100</span>)</span>}> <span class="hljs-title">A</span> <span class="hljs-title">route</span> <span class="hljs-title">transition</span> <span class="hljs-title">will</span> <span class="hljs-title">happen</span> <span class="hljs-title">after</span> 100<span class="hljs-title">ms</span> </<span class="hljs-title">a</span>> {// <span class="hljs-title">but</span> <span class="hljs-title">we</span> <span class="hljs-title">can</span> <span class="hljs-title">prefetch</span> <span class="hljs-title">it</span>! <span class="hljs-title">Router</span>.<span class="hljs-title">prefetch</span><span class="hljs-params">(<span class="hljs-string">'/dynamic'</span>)</span>} </<span class="hljs-title">div</span>></span></code></pre> <h3 id="自定义服务器和路由">自定义服务器和路由</h3> <p> <b>Examples</b> </p> <ul> <li>Basic custom server</li> <li>Express integration</li> <li>Hapi integration</li> <li>Koa integration</li> <li>Parameterized routing</li> <li>SSR caching</li> </ul> <p></p> <p>一般来说,你可以使用 <code>next start</code>命令启动 <code>next</code>服务,但是,你也完全可以使用编程(<code>programmatically</code>)的方式,例如路由匹配等,来定制化路由。</p> <p>下面就是一个将 <code>/a</code>匹配到 <code>./page/b</code>,以及将 <code>/b</code>匹配到 <code>./page/a</code>的例子:</p> <pre class="prettyprint"><code class="language-js hljs "><span class="hljs-comment">// This file doesn't not go through babel or webpack transformation.</span> <span class="hljs-comment">// Make sure the syntax and sources this file requires are compatible with the current node version you are running</span> <span class="hljs-comment">// See https://github.com/zeit/next.js/issues/1245 for discussions on Universal Webpack or universal Babel</span> <span class="hljs-keyword">const</span> { createServer } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'http'</span>) <span class="hljs-keyword">const</span> { parse } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'url'</span>) <span class="hljs-keyword">const</span> next = <span class="hljs-built_in">require</span>(<span class="hljs-string">'next'</span>) <span class="hljs-keyword">const</span> dev = process.env.NODE_ENV !== <span class="hljs-string">'production'</span> <span class="hljs-keyword">const</span> app = next({ dev }) <span class="hljs-keyword">const</span> handle = app.getRequestHandler() app.prepare().then(() => { createServer((req, res) => { <span class="hljs-comment">// Be sure to pass `true` as the second argument to `url.parse`.</span> <span class="hljs-comment">// This tells it to parse the query portion of the URL.</span> <span class="hljs-keyword">const</span> parsedUrl = parse(req.url, <span class="hljs-literal">true</span>) <span class="hljs-keyword">const</span> { pathname, query } = parsedUrl <span class="hljs-keyword">if</span> (pathname === <span class="hljs-string">'/a'</span>) { app.render(req, res, <span class="hljs-string">'/b'</span>, query) } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (pathname === <span class="hljs-string">'/b'</span>) { app.render(req, res, <span class="hljs-string">'/a'</span>, query) } <span class="hljs-keyword">else</span> { handle(req, res, parsedUrl) } }).listen(<span class="hljs-number">3000</span>, err => { <span class="hljs-keyword">if</span> (err) <span class="hljs-keyword">throw</span> err console.log(<span class="hljs-string">'> Ready on http://localhost:3000'</span>) }) })</code></pre> <p><code>next API</code>如下所示: <br> - <code>next(path: string, opts: object)</code> - <code>path</code>是 <code>Next</code>应用当前的路由位置 <br> - <code>next(opts: object)</code></p> <p>上述 <code>API</code>中的 <code>opt</code>对象存在如下属性: <br> - <code>dev</code> (<code>bool</code>) 是否使用开发模式(<code>dev</code>)来启动 <code>Next.js</code> - 默认为 <code>false</code> <br> - <code>dir</code> (<code>string</code>) 当前 <code>Next</code>应用的路由位置 - 默认为 <code>'.'</code> <br> - <code>quiet</code> (<code>bool</code>) 隐藏包括服务器端消息在内的错误消息 - 默认为 <code>false</code> <br> - <code>conf</code> (<code>object</code>) 和<code>next.config.js</code> 中的对象是同一个 - 默认为 <code>{}</code></p> <p>然后,将你(在 <code>package.json</code>中配置)的 <code>start</code>命令(<code>script</code>)改写成 <code>NODE_ENV=production node server.js</code>。</p> <h3 id="异步导入-dynamic-import">异步导入 Dynamic Import</h3> <p> <b>Examples</b> </p> <ul> <li>With Dynamic Import</li> </ul> <p></p> <p><code>Next.js</code>支持 <code>JavaScript TC39</code> 的dynamic import proposal规范,所以你可以动态导入(<code>import</code>) <code>JavaScript</code> 模块(例如 <code>React Component</code>)。</p> <p>你可以将动态导入理解为一种将代码分割为更易管理和理解的方式。 <br> 由于 <code>Next.js</code>支持服务器端渲染侧(<code>SSR</code>)的动态导入,所以你可以用它来做一些炫酷的东西。</p> <h4 id="1-基本用法同样支持-ssr">1. 基本用法(同样支持 <code>SSR</code>)</h4> <pre class="prettyprint"><code class="language-jsx hljs coffeescript"><span class="hljs-reserved">import</span> dynamic from <span class="hljs-string">'next/dynamic'</span> <span class="hljs-reserved">const</span> DynamicComponent = dynamic(<span class="hljs-reserved">import</span>(<span class="hljs-string">'../components/hello'</span>)) <span class="hljs-reserved">export</span> <span class="hljs-reserved">default</span> <span class="hljs-function"><span class="hljs-params">()</span> =></span> <div> <Header /> <DynamicComponent /> <p>HOME PAGE <span class="hljs-keyword">is</span> here!</p> </div></code></pre> <h4 id="2-自定义-加载组件">2. 自定义 加载组件</h4> <pre class="prettyprint"><code class="language-jsx hljs coffeescript"><span class="hljs-reserved">import</span> dynamic from <span class="hljs-string">'next/dynamic'</span> <span class="hljs-reserved">const</span> DynamicComponentWithCustomLoading = dynamic( <span class="hljs-reserved">import</span>(<span class="hljs-string">'../components/hello2'</span>), { <span class="hljs-attribute">loading</span>: <span class="hljs-function"><span class="hljs-params">()</span> =></span> <p>...</p> } ) <span class="hljs-reserved">export</span> <span class="hljs-reserved">default</span> <span class="hljs-function"><span class="hljs-params">()</span> =></span> <div> <Header /> <DynamicComponentWithCustomLoading /> <p>HOME PAGE <span class="hljs-keyword">is</span> here!</p> </div></code></pre> <h4 id="3-禁止-ssr">3. 禁止 <code>SSR</code></h4> <pre class="prettyprint"><code class="language-jsx hljs coffeescript"><span class="hljs-reserved">import</span> dynamic from <span class="hljs-string">'next/dynamic'</span> <span class="hljs-reserved">const</span> DynamicComponentWithNoSSR = dynamic(<span class="hljs-reserved">import</span>(<span class="hljs-string">'../components/hello3'</span>), { <span class="hljs-attribute">ssr</span>: <span class="hljs-literal">false</span> }) <span class="hljs-reserved">export</span> <span class="hljs-reserved">default</span> <span class="hljs-function"><span class="hljs-params">()</span> =></span> <div> <Header /> <DynamicComponentWithNoSSR /> <p>HOME PAGE <span class="hljs-keyword">is</span> here!</p> </div></code></pre> <h4 id="4-一次性加载多个模块">4. 一次性加载多个模块</h4> <pre class="prettyprint"><code class="language-jsx hljs coffeescript"><span class="hljs-reserved">import</span> dynamic from <span class="hljs-string">'next/dynamic'</span> <span class="hljs-reserved">const</span> HelloBundle = dynamic({ <span class="hljs-attribute">modules</span>: props<span class="hljs-function"> =></span> { <span class="hljs-reserved">const</span> components = { <span class="hljs-attribute">Hello1</span>: <span class="hljs-reserved">import</span>(<span class="hljs-string">'../components/hello1'</span>), <span class="hljs-attribute">Hello2</span>: <span class="hljs-reserved">import</span>(<span class="hljs-string">'../components/hello2'</span>) } <span class="hljs-regexp">//</span> Add remove components based <span class="hljs-literal">on</span> props <span class="hljs-keyword">return</span> components }, <span class="hljs-attribute">render</span>: <span class="hljs-function"><span class="hljs-params">(props, { Hello1, Hello2 })</span> =></span> <div> <h1> {props.title} </h1> <Hello1 /> <Hello2 /> </div> }) <span class="hljs-reserved">export</span> <span class="hljs-reserved">default</span> <span class="hljs-function"><span class="hljs-params">()</span> =></span> <HelloBundle title=<span class="hljs-string">"Dynamic Bundle"</span> /></code></pre> <h3 id="自定义-document">自定义 <code><Document></code></h3> <p> <b>Examples</b> </p> <ul> <li>Styled components custom document</li> </ul> <ul> <li>Google AMP</li> </ul> <p></p> <p><code>Next.js</code>帮你自动跳过了在为页面添加文档标记元素的操作,例如, 你从来不需要主动添加 <code><html></code>、<code><body></code>这些文档元素。如果你想重定义这些默认操作的话,那么你可以创建(或覆写) <code>./page/_ducument.js</code>文件,在此文件中,对 <code>Document</code>进行扩展:</p> <pre class="prettyprint"><code class="language-jsx hljs php"><span class="hljs-comment">// ./pages/_document.js</span> import Document, { Head, Main, NextScript } from <span class="hljs-string">'next/document'</span> import flush from <span class="hljs-string">'styled-jsx/server'</span> export <span class="hljs-keyword">default</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyDocument</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Document</span> {</span> <span class="hljs-keyword">static</span> getInitialProps({ renderPage }) { <span class="hljs-keyword">const</span> { html, head, errorHtml, chunks } = renderPage() <span class="hljs-keyword">const</span> styles = flush() <span class="hljs-keyword">return</span> { html, head, errorHtml, chunks, styles } } render() { <span class="hljs-keyword">return</span> ( <html> <Head> <style>{`body { margin: <span class="hljs-number">0</span> } <span class="hljs-comment">/* custom! */</span>`}</style> </Head> <body className=<span class="hljs-string">"custom_class"</span>> {this.props.customValue} <Main /> <NextScript /> </body> </html> ) } }</code></pre> <p>在以下前提下,所有的 <code>getInitialProps</code> 钩子函数接收到的 <code>ctx</code>都指的是同一个对象:</p> <ul> <li>回调函数 <code>renderPage</code> (<code>Function</code>)是真正执行 <code>React</code>渲染逻辑的函数(同步地),这种做法有助于此函数支持一些类似于 <code>Aphrodite's</code>的 <code>renderStatic</code>等一些服务器端渲染容器。</li> </ul> <p><em>注意:<code><Main/></code>之外的 <code>React</code>组件都不会被浏览器初始化,如果你想在所有的页面中使用某些组件(例如菜单栏或者工具栏),首先保证不要在其中添加有关应用逻辑的内容,然后可以看看这个例子</em></p> <h3 id="自定义错误处理">自定义错误处理</h3> <p>客户端和服务器端都会捕获并使用默认组件 <code>error.js</code>来处理 <code>404</code> 和 <code>500</code>错误。如果你希望自定义错误处理,可以对其进行覆写:</p> <pre class="prettyprint"><code class="language-jsx hljs axapta">import React from <span class="hljs-string">'react'</span> export <span class="hljs-keyword">default</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Error</span> <span class="hljs-inheritance"><span class="hljs-keyword">extends</span></span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span> {</span> <span class="hljs-keyword">static</span> getInitialProps({ res, jsonPageRes }) { const statusCode = res ? res.statusCode : jsonPageRes ? jsonPageRes.status : <span class="hljs-keyword">null</span> <span class="hljs-keyword">return</span> { statusCode } } render() { <span class="hljs-keyword">return</span> ( <p> {<span class="hljs-keyword">this</span>.props.statusCode ? `An error ${<span class="hljs-keyword">this</span>.props.statusCode} occurred on <span class="hljs-keyword">server</span>` : <span class="hljs-string">'An error occurred on client'</span>} </p> ) } }</code></pre> <h3 id="使用内置的错误页面">使用内置的错误页面</h3> <p>如果你想使用内置的错误页面,那么你可以通过 <code>next/error</code>来实现:</p> <pre class="prettyprint"><code class="language-jsx hljs axapta">import React from <span class="hljs-string">'react'</span> import Error from <span class="hljs-string">'next/error'</span> import fetch from <span class="hljs-string">'isomorphic-fetch'</span> export <span class="hljs-keyword">default</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Page</span> <span class="hljs-inheritance"><span class="hljs-keyword">extends</span></span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span> {</span> <span class="hljs-keyword">static</span> async getInitialProps() { const res = await fetch(<span class="hljs-string">'https://api.github.com/repos/zeit/next.js'</span>) const statusCode = res.statusCode > <span class="hljs-number">200</span> ? res.statusCode : <span class="hljs-keyword">false</span> const json = await res.json() <span class="hljs-keyword">return</span> { statusCode, stars: json.stargazers_count } } render() { <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.props.statusCode) { <span class="hljs-keyword">return</span> <Error statusCode={<span class="hljs-keyword">this</span>.props.statusCode} /> } <span class="hljs-keyword">return</span> ( <<span class="hljs-keyword">div</span>> Next stars: {<span class="hljs-keyword">this</span>.props.stars} </<span class="hljs-keyword">div</span>> ) } }</code></pre> <blockquote> <p>如果你想使用自定义的错误页面,那么你可以导入你自己的错误(<code>_error</code>)页面组件而非内置的 <code>next/error</code></p> <p>译者注: <br> 如果你只是想覆写默认的错误页面,那么可以在 <code>/pages</code>下新建一个名为 <code>_error.js</code>的文件,<code>Next</code>将使用此文件来覆盖默认的错误页面</p> </blockquote> <h3 id="自定义配置">自定义配置</h3> <p>为了对 <code>Next.js</code>进行更复杂的自定义操作,你可以在项目的根目录下(和 <code>pages/</code>以及 <code>package.json</code>属于同一层级)新建一个 <code>nexr.config.js</code>文件</p> <p>注意:<code>next.confgi.js</code>是一个标准的 <code>Node.js</code>模块,而不是一个 <code>JSON</code>文件,此文件在 <code>Next</code>项目的服务端以及 <code>build</code>阶段会被调用,但是在浏览器端构建时是不会起作用的。</p> <pre class="prettyprint"><code class="language-js hljs "><span class="hljs-comment">// next.config.js</span> module.exports = { <span class="hljs-comment">/* config options here */</span> }</code></pre> <h4 id="设置一个自定义的构建build目录">设置一个自定义的构建(<code>build</code>)目录</h4> <p>你可以自行指定构建打包的输出目录,例如,下面的配置将会创建一个 <code>build</code>目录而不是 <code>.next</code>作为构建打包的输出目录,如果没有特别指定的话,那么默认就是 <code>.next</code></p> <pre class="prettyprint"><code class="language-js hljs "><span class="hljs-comment">// next.config.js</span> module.exports = { distDir: <span class="hljs-string">'build'</span> }</code></pre> <h4 id="configuring-the-ondemandentries">Configuring the onDemandEntries</h4> <p><code>Next</code> 暴露了一些能够让你自己控制如何部署服务或者缓存页面的配置:</p> <pre class="prettyprint"><code class="language-js hljs ">module.exports = { onDemandEntries: { <span class="hljs-comment">// 控制页面在内存`buffer`中缓存的时间,单位是 ms</span> maxInactiveAge: <span class="hljs-number">25</span> * <span class="hljs-number">1000</span>, <span class="hljs-comment">// number of pages that should be kept simultaneously without being disposed</span> pagesBufferLength: <span class="hljs-number">2</span>, } }</code></pre> <h3 id="自定义-webpack-配置">自定义 webpack 配置</h3> <p> <b>Examples</b> </p> <ul> <li>Custom webpack bundle analyzer</li> </ul> <p></p> <p>你可以通过 <code>next.config.js</code>中的函数来扩展 <code>webpack</code>的配置</p> <pre class="prettyprint"><code class="language-js hljs "><span class="hljs-comment">// This file is not going through babel transformation.</span> <span class="hljs-comment">// So, we write it in vanilla JS</span> <span class="hljs-comment">// (But you could use ES2015 features supported by your Node.js version)</span> module.exports = { webpack: (config, { buildId, dev }) => { <span class="hljs-comment">// Perform customizations to webpack config</span> <span class="hljs-comment">// Important: return the modified config</span> <span class="hljs-keyword">return</span> config }, webpackDevMiddleware: config => { <span class="hljs-comment">// Perform customizations to webpack dev middleware config</span> <span class="hljs-comment">// Important: return the modified config</span> <span class="hljs-keyword">return</span> config } }</code></pre> <p><em>警告:不推荐在 <code>webpack</code>的配置中添加一个支持新文件类型(<code>css less svg</code>等)的 <code>loader</code>,因为 <code>webpack</code>只会打包客户端代码,所以(<code>loader</code>)不会在服务器端的初始化渲染中起作用。<code>Babel</code>是一个很好的替代品,因为其给服务器端和客户端提供一致的功能效果(例如,babel-plugin-inline-react-svg)。</em></p> <h3 id="自定义-babel-配置">自定义 Babel 配置</h3> <p> <b>Examples</b> </p> <ul> <li>Custom babel configuration</li> </ul> <p></p> <p>为了扩展对 <code>Babel</code>的使用,你可以在应用的根目录下新建 <code>.babelrc</code>文件,此文件是非必须的。 <br> 如果此文件存在,那么我们就认为这个才是真正的<code>Babel</code>配置文件,因此也就需要为其定义一些 <code>next</code>项目需要的东西, 并将之当做是<code>next/babel</code>的预设配置(<code>preset</code>) <br> 这种设计是为了避免你有可能对我们能够定制 <code>babel</code>配置而感到诧异。</p> <p>下面是一个 <code>.babelrc</code>文件的示例:</p> <pre class="prettyprint"><code class="language-json hljs ">{ "<span class="hljs-attribute">presets</span>": <span class="hljs-value">[<span class="hljs-string">"next/babel"</span>, <span class="hljs-string">"stage-0"</span>] </span>}</code></pre> <h3 id="cdn-支持">CDN 支持</h3> <p>你可以设定 <code>assetPrefix</code>项来配置 <code>CDN</code>源,以便能够与 <code>Next.js</code>项目的 <code>host</code>保持对应。</p> <pre class="prettyprint"><code class="language-js hljs "><span class="hljs-keyword">const</span> isProd = process.env.NODE_ENV === <span class="hljs-string">'production'</span> module.exports = { <span class="hljs-comment">// You may only need to add assetPrefix in the production.</span> assetPrefix: isProd ? <span class="hljs-string">'https://cdn.mydomain.com'</span> : <span class="hljs-string">''</span> }</code></pre> <p>注意:<code>Next.js</code>将会自动使用所加载脚本的 <code>CDN</code>域(作为项目的 <code>CDN</code>域),但是对 <code>/static</code>目录下的静态文件就无能为力了。如果你想让那些静态文件也能用上<code>CDN</code>,那你就不得不要自己指定 <code>CDN</code>域,有种方法也可以让你的项目自动根据运行环境来确定 <code>CDN</code>域,可以看看这个例子</p> <h2 id="项目部署">项目部署</h2> <p>构建打包和启动项目被分成了以下两条命令:</p> <pre class="prettyprint"><code class="language-bash hljs ">next build next start</code></pre> <p>例如,你可以像下面这样为 <code>now</code>项目配置 <code>package.json</code>文件:</p> <pre class="prettyprint"><code class="language-json hljs ">{ "<span class="hljs-attribute">name</span>": <span class="hljs-value"><span class="hljs-string">"my-app"</span></span>, "<span class="hljs-attribute">dependencies</span>": <span class="hljs-value">{ "<span class="hljs-attribute">next</span>": <span class="hljs-value"><span class="hljs-string">"latest"</span> </span>}</span>, "<span class="hljs-attribute">scripts</span>": <span class="hljs-value">{ "<span class="hljs-attribute">dev</span>": <span class="hljs-value"><span class="hljs-string">"next"</span></span>, "<span class="hljs-attribute">build</span>": <span class="hljs-value"><span class="hljs-string">"next build"</span></span>, "<span class="hljs-attribute">start</span>": <span class="hljs-value"><span class="hljs-string">"next start"</span> </span>} </span>}</code></pre> <p>然后就可以直接启动 <code>now</code>项目了!</p> <p><code>Next.js</code>也可以使用其他的托管方案,更多详细可以看一下这部分内容 ‘Deployment’ <br> 注意:我们推荐你推送 <code>.next</code>,或者你自定义的打包输出目录(到托管方案上)(Please have a look at ‘Custom Config’,你还可以自定义一个专门用于放置配置文件(例如 <code>.npmignore</code>或 <code>.gitignore</code>)的文件夹。否则的话,使用 <code>files</code>或者 <code>now.files</code>来选择要部署的白名单(很明显要排除掉 <code>.next</code>或你自定义的打包输出目录)</p> <h2 id="导出静态-html-页面">导出静态 HTML 页面</h2> <p> <b>Examples</b> </p> <ul> <li>Static export</li> </ul> <p></p> <p>你可以将你的 <code>Next.js</code>应用当成一个不依赖于 <code>Node.js服务的</code>静态应用。此静态应用支持几乎所有的 <code>Next.js</code>特性,包括 异步导航、预获取、预加载和异步导入等。</p> <h3 id="使用">使用</h3> <p>首先,<code>Next.js</code>的开发工作没什么变化,然后创建一个 <code>Next.js</code>的配置文件 config,就像下面这样:</p> <pre class="prettyprint"><code class="language-js hljs "><span class="hljs-comment">// next.config.js</span> module.exports = { exportPathMap: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> {</span> <span class="hljs-keyword">return</span> { <span class="hljs-string">'/'</span>: { page: <span class="hljs-string">'/'</span> }, <span class="hljs-string">'/about'</span>: { page: <span class="hljs-string">'/about'</span> }, <span class="hljs-string">'/readme.md'</span>: { page: <span class="hljs-string">'/readme'</span> }, <span class="hljs-string">'/p/hello-nextjs'</span>: { page: <span class="hljs-string">'/post'</span>, query: { title: <span class="hljs-string">'hello-nextjs'</span> } }, <span class="hljs-string">'/p/learn-nextjs'</span>: { page: <span class="hljs-string">'/post'</span>, query: { title: <span class="hljs-string">'learn-nextjs'</span> } }, <span class="hljs-string">'/p/deploy-nextjs'</span>: { page: <span class="hljs-string">'/post'</span>, query: { title: <span class="hljs-string">'deploy-nextjs'</span> } } } } }</code></pre> <blockquote> <p>需要注意的是,如果声明的路径表示的是一个文件夹的话,那么最终将会导出一份类似于 <code>/dir-name/index.html</code>的文件,如果声明的路径是一个文件的话,那么最终将会以指定的文件名导出,例如上述代码中,就会导出一个 <code>readme.md</code>的文件。如果你使用了一个不是以 <code>.html</code>结尾的文件,那么在解析此文件的时候,你需要给 <code>text/html</code>设置一个 <code>Content-Type</code>头(<code>header</code>)</p> </blockquote> <p>通过上述的类似代码,你可以指定你想要导出的静态页面。</p> <p>接着,输入以下命令:</p> <pre class="prettyprint"><code class="language-sh hljs ruby"><span class="hljs-keyword">next</span> build <span class="hljs-keyword">next</span> export</code></pre> <p>或许,你还可以在 <code>package.json</code>文件中多添加一条命令:</p> <pre class="prettyprint"><code class="language-json hljs ">{ "<span class="hljs-attribute">scripts</span>": <span class="hljs-value">{ "<span class="hljs-attribute">build</span>": <span class="hljs-value"><span class="hljs-string">"next build && next export"</span> </span>} </span>}</code></pre> <p>现在就只需要输入这一条命令就行了:</p> <pre class="prettyprint"><code class="language-sh hljs coffeescript"><span class="hljs-built_in">npm</span> run build</code></pre> <p>这样,你在 <code>out</code>目录下就有了一个当前应用的静态网站了。</p> <blockquote> <p>你也可以自定义输出目录,更多帮助可以在命令行中输入 <code>next export -h</code> 获取</p> </blockquote> <p>现在,你就可以把输出目录(例如<code>/out</code>)部署到静态文件服务器了,需要注意的是,如果你想要部署到 <code>Github</code>上的话,那么需要需要增加一个步骤</p> <p>例如,只需要进入 <code>out</code>目录,然后输入以下命令,就可以把你的应用部署到 ZEIT now</p> <pre class="prettyprint"><code class="language-sh hljs mizar"><span class="hljs-keyword">now</span></code></pre> <h3 id="局限性">局限性</h3> <p>当你输入 <code>next export</code>命令时,我们帮你构建了应用的 <code>HTML</code>静态版本,在此阶段,我们将会执行页面中的 <code>getInitialProps</code>函数。</p> <p>所以,你只能使用 <code>context</code>对象传递给 <code>getInitialProps</code>的 <code>pathname</code>、<code>query</code>和 <code>asPath</code> 字段,而 <code>req</code> 或 <code>res</code>则是不可用的(<code>res</code>和 <code>res</code>只在服务器端可用)。</p> <blockquote> <p>基于此,你也无法在我们预先构建 <code>HTML</code>文件的时候,动态的呈现 <code>HTML</code>页面,如果你真的想要这么做(指动态构建页面)的话,请使用 <code>next start</code></p> </blockquote> <h2 id="相关技巧">相关技巧</h2> <ul> <li>Setting up 301 redirects</li> <li>Dealing with SSR and server only modules</li> </ul> <h2 id="faq">FAQ</h2> <p> <br> 可用在生产环境使用吗? <br> https://zeit.co 就是使用 <code>Next.js</code>构建的。</p> <p>无论是开发者体验还是终端表现,它都超出预期,所以我们决定将它共享到社区中。 <br> </p> <p> <br> 体积有多大?</p> <p>客户端包的大小根据每个应用程序的功能等不同而不尽相同。 <br> 一个最简单的 <code>Next</code>程序包在 <code>gzip</code>压缩后可能只有 65kb 大小。</p> <p></p> <p> <br> 它(指Next.js) 和 <code>create-react-app</code>是差不多的吗?</p> <p>是也不是。 <br> 说是,是因为二者都让你的开发变得更轻松。 <br> 说不是,则是因为 <code>Next.js</code>强制规定了一些目录结构,以便我们能实现更多高级的操作,例如: <br> - 服务器端渲染(<code>SSR</code>) <br> - 代码自动分割</p> <p>此外,<code>Next.js</code>还内置了两个对于单页应用来说比较重要的特性: <br> - Routing with lazy component loading: <code><Link></code> (by importing <code>next/link</code>) <br> - 修改 <code><head></code>元素的方法(通过导入 <code>next/head</code>)</p> <p>如果你想在 <code>Next.js</code>或其他 <code>React</code>应用中复用组件,则使用 <code>create-react-app</code>是一个很好的选择,你可以稍后将其导入以保证代码库的纯净。</p> <p></p> <p> <br> 如何使用嵌入式CSS(<code>CSS-in-JS</code>)方案?</p> <p><code>Next.js</code>自带的库 styled-jsx支持 局部(<code>scoped</code>)<code>css</code>,当然,你也可以在 <code>Next</code>应用中添加上面所提到的任何你喜欢的代码库来使用你想要的 <code>CSS-in-JS</code>解决方案。 <br> </p> <p> <br> 如何使用类似于 SASS / SCSS / LESS 之类的 CSS 预处理器?</p> <p><code>Next.js</code>自带的库 styled-jsx支持 局部(<code>scoped</code>)<code>css</code>,当然,你也可以在 <code>Next</code>应用中使用以下示例中的任何一种 <code>CSS</code>预处理器方案:</p> <ul> <li>with-external-scoped-css</li> <li>with-scoped-stylesheets-and-postcss</li> <li>with-global-stylesheet</li> </ul> <p></p> <p> <br> What syntactic features are transpiled? How do I change them?</p> <p>(语法特性)我们参照 <code>V8</code>引擎,因为 <code>V8</code>广泛支持 <code>ES6</code> 和 <code>async</code> 以及 <code>await</code>,所以我们也就支持这些,因为 <code>V8</code>还不支持类装饰器(<code>class decorator</code>),所以我们也就不支持它(类装饰器)</p> <p>可以看看 这些 以及 这些</p> <p></p> <p> <br> Why a new Router?</p> <p>Next.js is special in that:</p> <ul> <li>Routes don’t need to be known ahead of time</li> <li>Routes are always lazy-loadable</li> <li>Top-level components can define <code>getInitialProps</code> that should <em>block</em> the loading of the route (either when server-rendering or lazy-loading)</li> </ul> <p>基于上述几个特点,我们能够构造出一个具有以下两个功能的简单路由: <br> - 每个顶级组件都会接收到一个 <code>url</code>对象来检查 <code>url</code> 或者 修改历史记录 <br> - <code><Link /></code>组件作为类似于 <code><a/></code>等标签元素的容器以便进行客户端的页面切换。</p> <p>我们已经在一些很有意思的场景下测试了路由的灵活性,更多相信可以看这里 nextgram <br> </p> <p> <br> 如何自定义路由?</p> <p><code>Next.js</code>提供了一个 <code>request handler</code>,利用其我们能够让任意 <code>URL</code>与 任何组件之间产生映射关系。 <br> 在客户端,<code><Link /></code>组件有个 <code>as</code>属性,它能够改变获取到的 <code>URL</code> <br> </p> <p> <br> 如何获取数据?</p> <p>这由你决定, <code>getInitialProps</code> 是一个 异步(<code>async</code>)函数(或者也可以说是一个返回 <code>Promise</code>的标准函数),它能够从任意位置获取数据。 <br> </p> <p> <br> 能够配合使用 <code>GraphQL</code>吗</p> <p>当然,这还有个用 Apollo 的例子呢。 <br> </p> <p> <br> 能够配合使用 <code>Redux</code>吗?</p> <p>当然,这也有个例子。 <br> </p> <p> <br> 为什么我不能在开发服务器中访问我的静态导出路由呢?</p> <p>这是一个已知的 <code>Next.js</code>架构问题,在解决方案还没内置到框架中之前,你可以先看看这一个例子中的解决方法来集中管理你的路由。 <br> </p> <p> <br> 我可以在 Next应用中使用我喜欢的 JavaScript库或工具包吗?</p> <p>我们在发布第一版的时候就已经提供了很多例子,你可以看看这个目录 <br> </p> <p> <br> 你们是怎么做出这个框架的?</p> <p>我们力求达到的目标大部分都是从 由 <code>Guillermo Rauch</code>给出的[设计富Web应用的 7个原则]中受到启发,<code>PHP</code>的易用性也是一个很棒的灵感来源,我们觉得在很多你想使用 <code>PHP</code>来输出 <code>HTML</code>页面的情况下,<code>Next.js</code>都是一个很好的替代品,不过不像 <code>PHP</code>,我们从 <code>ES6</code>的模块化系统中获得好处,每个文件都能很轻松地导入一个能够用于延迟求值或测试的组件或函数。</p> <p>当我们研究 <code>React</code>的服务器端渲染时,我们并没有做出太大的改变,因为我们偶然发现了 <code>React</code>作者 <code>Jordan Walke</code>写的 react-page (now deprecated)。 <br> </p> <h2 id="contributing">Contributing</h2> <p>Please see our contributing.md</p> <h2 id="authors">Authors</h2> <ul> <li>Arunoda Susiripala (@arunoda) – ▲ZEIT</li> <li>Tim Neutkens (@timneutkens)</li> <li>Naoyuki Kanezawa (@nkzawa) – ▲ZEIT</li> <li>Tony Kovanen (@tonykovanen) – ▲ZEIT</li> <li>Guillermo Rauch (@rauchg) – ▲ZEIT</li> <li>Dan Zajdband (@impronunciable) – Knight-Mozilla / Coral Project</li> </ul> </div> </div> </div> </div> </div> <!--PC和WAP自适应版--> <div id="SOHUCS" sid="1175190325417816064"></div> <script type="text/javascript" src="/views/front/js/chanyan.js"></script> <!-- 文章页-底部 动态广告位 --> <div class="youdao-fixed-ad" id="detail_ad_bottom"></div> </div> <div class="col-md-3"> <div class="row" id="ad"> <!-- 文章页-右侧1 动态广告位 --> <div id="right-1" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad"> <div class="youdao-fixed-ad" id="detail_ad_1"> </div> </div> <!-- 文章页-右侧2 动态广告位 --> <div id="right-2" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad"> <div class="youdao-fixed-ad" id="detail_ad_2"></div> </div> <!-- 文章页-右侧3 动态广告位 --> <div id="right-3" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad"> <div class="youdao-fixed-ad" id="detail_ad_3"></div> </div> </div> </div> </div> </div> </div> <div class="container"> <h4 class="pt20 mb15 mt0 border-top">你可能感兴趣的:(Web前端,React)</h4> <div id="paradigm-article-related"> <div class="recommend-post mb30"> <ul class="widget-links"> <li><a href="/article/1950193455162519552.htm" title="19.0-《超越感觉》-说服他人" target="_blank">19.0-《超越感觉》-说服他人</a> <span class="text-muted">SAM52</span> <div>Becausethoughtfuljudgmentsdeservetobeshared,andthewaytheyarepresentedcanstronglyinfluencethewayothersreacttothem.因为经过深思熟虑的判断值得分享,而这些判断的呈现方式会强烈影响其他人对它们的反应。Bylearningtheprinciplesofpersuasionandapplying</div> </li> <li><a href="/article/1950178478011772928.htm" title="全面解析:Spring Gateway如何优雅处理微服务的路由转发?" target="_blank">全面解析:Spring Gateway如何优雅处理微服务的路由转发?</a> <span class="text-muted">万猫学社</span> <a class="tag" taget="_blank" href="/search/gateway/1.htm">gateway</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a> <div>SpringGateway简介SpringGateway,这是一个基于Spring5、SpringBoot2和ProjectReactor的API网关。它旨在为微服务架构提供一个简单、有效的统一的API路由、限流、熔断等功能。在微服务的世界里,SpringGateway就像一个交通警察,负责指挥和引导各个微服务之间的交通。相较于其他的网关技术,比如Nginx、Zuul等,SpringGateway</div> </li> <li><a href="/article/1950169526440095744.htm" title="从零到一:打造基于GigaChat AI的艺术创作平台 | 笙囧同学的全栈开发实战" target="_blank">从零到一:打造基于GigaChat AI的艺术创作平台 | 笙囧同学的全栈开发实战</a> <span class="text-muted"></span> <div>作者简介:笙囧同学,中科院计算机大模型方向硕士,全栈开发爱好者联系方式:3251736703@qq.com各大平台账号:笙囧同学座右铭:偷懒是人生进步的阶梯前言在AI技术飞速发展的今天,如何将前沿的大模型技术与实际应用相结合,一直是我们开发者关注的焦点。今天,笙囧同学将带大家从零开始,构建一个基于GigaChatAI的艺术创作平台,实现React前端+Django后端的完整全栈解决方案。这不仅仅是</div> </li> <li><a href="/article/1950144218282389504.htm" title="为什么学习Web前端一定要掌握JavaScript?" target="_blank">为什么学习Web前端一定要掌握JavaScript?</a> <span class="text-muted">web前端学习指南</span> <div>为什么学习Web前端一定要掌握JavaScript?在前端的世界里,没有什么是JavaScript实现不了的,关于JS有一句话:凡是可以用JavaScript来写的应用,最终都会用JavaScript,JavaScript可运行在所有主要平台的所有主流浏览器上,也可运行在每一个主流操作系统的服务器端上。现如今我们在为网站写任何一个主要功能的时候都需要有懂能够用JavaScript写前端的开发人员。</div> </li> <li><a href="/article/1950055310613868544.htm" title="Vue3组合API初体验" target="_blank">Vue3组合API初体验</a> <span class="text-muted">DTcode7</span> <a class="tag" taget="_blank" href="/search/Vue%E5%AE%9E%E6%88%98%E6%8C%87%E5%8D%97/1.htm">Vue实战指南</a><a class="tag" taget="_blank" href="/search/VUE/1.htm">VUE</a><a class="tag" taget="_blank" href="/search/HTML/1.htm">HTML</a><a class="tag" taget="_blank" href="/search/web/1.htm">web</a><a class="tag" taget="_blank" href="/search/vue%E6%A1%86%E6%9E%B6/1.htm">vue框架</a><a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a> <div>Vue3组合API初体验基本概念与作用说明示例一:使用ref创建响应式数据示例二:使用reactive创建响应式对象示例三:使用computed计算属性示例四:使用watch监听数据变化示例五:使用provide/inject进行父子组件间通信功能使用思路与实际开发技巧1.何时使用ref与reactive?2.如何在组合式API中保持逻辑的清晰?3.如何处理异步操作?随着Vue3的发布,组合式AP</div> </li> <li><a href="/article/1950020001654173696.htm" title="Web前端交互利用Python跟大模型操作" target="_blank">Web前端交互利用Python跟大模型操作</a> <span class="text-muted">哥本哈士奇</span> <a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a><a class="tag" taget="_blank" href="/search/%E4%BA%A4%E4%BA%92/1.htm">交互</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a> <div>Web前端交互利用Python跟大模型操作一个简单的演示,如何把大模型应用集成到自己的应用场景当中。这里的场景我们模拟的是在吃鸡游戏中,一个作战计划,是否符合老六的行为规范。吃鸡游戏已经风靡很多年,游戏里每个人的游戏风格都不一样,有喜欢钢枪的,有喜欢随机应变的,也有喜欢当老六苟分的。每种风格的游戏方式以及游戏里的行为都不同,所以这里将演示如何应用大模型,去判断一个人的游戏方式,是否符合一个老六的行</div> </li> <li><a href="/article/1949951567260086272.htm" title="第七篇 快速开始-序" target="_blank">第七篇 快速开始-序</a> <span class="text-muted">深圳都这么冷</span> <div>快速开始欢迎使用React文档!本页将向您介绍您每天会用到的80%的React概念。本章内容预告如何创建和嵌套组件如何添加标记和样式如何显示数据如何渲染条件表达式和列表表达式如何响应事件和更新屏幕如何在组件之间共享数据创建和嵌套组件React应用程序由组件组成。组件是UI(用户界面)的一部分,具有自己的逻辑和外观。组件可以小到一个按钮,也可以大到整个页面。React组件是返回标记的JavaScri</div> </li> <li><a href="/article/1949936521918345216.htm" title="maven指定子项目打包" target="_blank">maven指定子项目打包</a> <span class="text-muted"></span> <div>Maven多个mudule只编译、打包指定module在多module的maven项目中,如果每次打包整个工程显得有些冗余和笨重。例如A,B,P的继承关系为P|—–A|—–B即P包含A,B的module,每次打包P都会将A,B都打包。假如我只修改了A模块,那么每次都要将B都一块打包吗?当然不是,maven提供了自定义参数:-pl,--projectsBuildspecifiedreactorpro</div> </li> <li><a href="/article/1949935132882300928.htm" title="React组件中的this指向问题" target="_blank">React组件中的this指向问题</a> <span class="text-muted"></span> <div>在React组件中,函数定义方式影响this指向的核心原因是箭头函数与普通函数的作用域绑定规则不同,具体差异如下:1.普通函数(function定义)需要手动bind(this)的原因当用function在组件内定义方法时:classMyComponentextendsReact.Component{handleClick(){console.log(this);//若未绑定,此处this为und</div> </li> <li><a href="/article/1949861487262625792.htm" title="Rust 全栈应用框架 Dioxus:从前端到桌面再到 WASM 的统一开发体验" target="_blank">Rust 全栈应用框架 Dioxus:从前端到桌面再到 WASM 的统一开发体验</a> <span class="text-muted">掘金安东尼</span> <a class="tag" taget="_blank" href="/search/%E5%AD%97%E8%8A%82/1.htm">字节</a><a class="tag" taget="_blank" href="/search/%E9%98%BF%E9%87%8C/1.htm">阿里</a><a class="tag" taget="_blank" href="/search/rust/1.htm">rust</a><a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a><a class="tag" taget="_blank" href="/search/wasm/1.htm">wasm</a> <div>如果你正在寻找一个能用Rust写前端、桌面应用、移动应用甚至WebAssembly的统一框架,Dioxus是目前生态中最具潜力的选择之一。为什么需要Dioxus?随着WebAssembly(WASM)与Rust的发展,越来越多开发者开始思考:Rust是否能做“全栈”?是否能有像React一样的组件模型?是否可以用Rust写桌面GUI,甚至Web前端?Dioxus正是这个愿景下的产物。它是一个受Re</div> </li> <li><a href="/article/1949767053955100672.htm" title="web前端总复习(一):http和https" target="_blank">web前端总复习(一):http和https</a> <span class="text-muted">做一个暴躁的开发</span> <a class="tag" taget="_blank" href="/search/web%E5%89%8D%E7%AB%AF%E6%80%BB%E5%A4%8D%E4%B9%A0/1.htm">web前端总复习</a><a class="tag" taget="_blank" href="/search/http/1.htm">http</a><a class="tag" taget="_blank" href="/search/%E7%BD%91%E7%BB%9C/1.htm">网络</a><a class="tag" taget="_blank" href="/search/https/1.htm">https</a> <div>http和https的基本概念http:超文本传输协议,是互联网上应用最为广泛的一种网络协议,是一种用于从服务器传输超文本到本地浏览器的传输协议。它可以使得浏览器更加高效,减少网络传输。https:是http的安全版。是一种以安全为目标的http通道。http和https的区别①http传输信息不加密,https传输信息加密。②端口不同,http为80端口,https为443端口。③https协议</div> </li> <li><a href="/article/1949740580871401472.htm" title="IntelliJ IDEA 高效开发指南:从基础操作到高级技巧" target="_blank">IntelliJ IDEA 高效开发指南:从基础操作到高级技巧</a> <span class="text-muted">zqmgx13291</span> <a class="tag" taget="_blank" href="/search/intellij-idea/1.htm">intellij-idea</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/ide/1.htm">ide</a> <div>一、IDEA概述与环境配置1.1IDEA的核心优势智能代码辅助:基于上下文的代码补全(Ctrl+Space)、方法参数提示、错误实时检测全栈开发支持:内置Java/Python/JavaScript等20+语言支持,框架集成(SpringBoot/Vue/React)工具链集成:版本控制(Git/SVN)、数据库(MySQL/PostgreSQL)、容器(Docker/K8s)一站式开发性能优化:</div> </li> <li><a href="/article/1949548048325603328.htm" title="react class和function 如何模拟vue中的 双向绑定 监听 computed的方式" target="_blank">react class和function 如何模拟vue中的 双向绑定 监听 computed的方式</a> <span class="text-muted"></span> <div>在React中,类组件和函数组件的写法有所不同。你提到的「双向绑定」、「监听」和「computed(计算属性)」这几个概念,原本来源于Vue,但在React中我们也可以通过特定方式实现类似功能。下面我将分别介绍:1.类组件中的双向绑定在类组件中,要实现双向绑定(如表单输入),我们通常使用state和onChange:importReactfrom'react';classMyFormextends</div> </li> <li><a href="/article/1949546785684910080.htm" title="PostGIS面试题及详细答案120道之 (021-030 )" target="_blank">PostGIS面试题及详细答案120道之 (021-030 )</a> <span class="text-muted">还是大剑师兰特</span> <a class="tag" taget="_blank" href="/search/%E5%A4%A7%E5%89%91%E5%B8%88/1.htm">大剑师</a><a class="tag" taget="_blank" href="/search/postgis%E9%9D%A2%E8%AF%95%E9%A2%98/1.htm">postgis面试题</a> <div>《前后端面试题》专栏集合了前后端各个知识模块的面试题,包括html,javascript,css,vue,react,java,Openlayers,leaflet,cesium,mapboxGL,threejs,nodejs,mangoDB,MySQL,Linux…。前后端面试题-专栏总目录文章目录一、本文面试题目录21.为什么要在PostGIS中使用空间索引?22.PostGIS支持哪些类型的</div> </li> <li><a href="/article/1949546658601693184.htm" title="Java面试题及详细答案120道之(081-100)" target="_blank">Java面试题及详细答案120道之(081-100)</a> <span class="text-muted">还是大剑师兰特</span> <a class="tag" taget="_blank" href="/search/%E5%89%8D%E5%90%8E%E7%AB%AF%E9%9D%A2%E8%AF%95%E9%A2%98/1.htm">前后端面试题</a><a class="tag" taget="_blank" href="/search/%E5%A4%A7%E5%89%91%E5%B8%88/1.htm">大剑师</a><a class="tag" taget="_blank" href="/search/java%E9%9D%A2%E8%AF%95%E9%A2%98/1.htm">java面试题</a> <div>《前后端面试题》专栏集合了前后端各个知识模块的面试题,包括html,javascript,css,vue,react,java,Openlayers,leaflet,cesium,mapboxGL,threejs,nodejs,mangoDB,MySQL,Linux…。前后端面试题-专栏总目录文章目录一、本文面试题目录81.Java中的`ConcurrentHashMap`与`HashMap`在并</div> </li> <li><a href="/article/1949546532227313664.htm" title="Openlayers 面试题及答案180道(41-60)" target="_blank">Openlayers 面试题及答案180道(41-60)</a> <span class="text-muted">还是大剑师兰特</span> <a class="tag" taget="_blank" href="/search/%23/1.htm">#</a><a class="tag" taget="_blank" href="/search/%E5%89%8D%E5%90%8E%E7%AB%AF%E9%9D%A2%E8%AF%95%E9%A2%98/1.htm">前后端面试题</a><a class="tag" taget="_blank" href="/search/%E5%A4%A7%E5%89%91%E5%B8%88/1.htm">大剑师</a><a class="tag" taget="_blank" href="/search/Openlayers%E9%9D%A2%E8%AF%95%E9%A2%98/1.htm">Openlayers面试题</a><a class="tag" taget="_blank" href="/search/Openlayers%E7%A4%BA%E4%BE%8B/1.htm">Openlayers示例</a><a class="tag" taget="_blank" href="/search/Openlayers%E6%95%99%E7%A8%8B/1.htm">Openlayers教程</a> <div>《前后端面试题》专栏集合了前后端各个知识模块的面试题,包括html,javascript,css,vue,react,java,Openlayers,leaflet,cesium,mapboxGL,threejs,nodejs,mangoDB,MySQL,Linux…。前后端面试题-专栏总目录文章目录一、本文面试题目录41.如何在OpenLayers中加载WFS数据?42.在OpenLayers中</div> </li> <li><a href="/article/1949540859238215680.htm" title="CSS面试题及详细答案140道之(41-60)" target="_blank">CSS面试题及详细答案140道之(41-60)</a> <span class="text-muted">还是大剑师兰特</span> <a class="tag" taget="_blank" href="/search/%E5%89%8D%E5%90%8E%E7%AB%AF%E9%9D%A2%E8%AF%95%E9%A2%98/1.htm">前后端面试题</a><a class="tag" taget="_blank" href="/search/css/1.htm">css</a><a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a><a class="tag" taget="_blank" href="/search/%E5%A4%A7%E5%89%91%E5%B8%88/1.htm">大剑师</a><a class="tag" taget="_blank" href="/search/CSS%E9%9D%A2%E8%AF%95/1.htm">CSS面试</a><a class="tag" taget="_blank" href="/search/CSS%E7%A4%BA%E4%BE%8B/1.htm">CSS示例</a> <div>《前后端面试题》专栏集合了前后端各个知识模块的面试题,包括html,javascript,css,vue,react,java,Openlayers,leaflet,cesium,mapboxGL,threejs,nodejs,mangoDB,MySQL,Linux…。前后端面试题-专栏总目录文章目录一、本文面试题目录41.如何在不使用额外标记的情况下隐藏文本但保留其可访问性?42.解释`text</div> </li> <li><a href="/article/1949536826452668416.htm" title="2025年02月13日 · Go生态洞察:可扩展的 WebAssembly 应用" target="_blank">2025年02月13日 · Go生态洞察:可扩展的 WebAssembly 应用</a> <span class="text-muted">猫头虎</span> <a class="tag" taget="_blank" href="/search/%23/1.htm">#</a><a class="tag" taget="_blank" href="/search/Go%E7%94%9F%E6%80%81%E6%B4%9E%E5%AF%9F/1.htm">Go生态洞察</a><a class="tag" taget="_blank" href="/search/golang/1.htm">golang</a><a class="tag" taget="_blank" href="/search/wasm/1.htm">wasm</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a><a class="tag" taget="_blank" href="/search/%E5%90%8E%E7%AB%AF/1.htm">后端</a><a class="tag" taget="_blank" href="/search/go1.19/1.htm">go1.19</a><a class="tag" taget="_blank" href="/search/go/1.htm">go</a><a class="tag" taget="_blank" href="/search/beego/1.htm">beego</a> <div>2025年02月13日·Go生态洞察:可扩展的WebAssembly应用摘要大家好,我是猫头虎。本篇文章将带领大家深入剖析Go1.24在WebAssembly(Wasm)领域的最新特性:go:wasmexport指令、WASIReactor构建模式、丰富类型支持及其限制,并通过示例代码演示如何在实际项目中灵活运用。关键词:WebAssembly、WASI、Go1.24、go:wasmexport、</div> </li> <li><a href="/article/1949467093661446144.htm" title="每天一个前端小知识 Day 17 - 微前端架构实战与 Module Federation" target="_blank">每天一个前端小知识 Day 17 - 微前端架构实战与 Module Federation</a> <span class="text-muted"></span> <div>微前端架构实战与ModuleFederation为什么要微前端?✅传统SPA的问题:问题描述构建时间越来越长单体应用构建缓慢,难以增量部署多团队协作困难不同业务线互相依赖紧耦合技术栈难以迁移老项目技术债,无法局部替换✅微前端目标:像微服务一样拆前端系统各子应用独立开发、独立部署、独立运行支持多技术栈共存(React+Vue+原生)核心架构方案一览架构方式技术实现适用场景iframe方式每个子应用独</div> </li> <li><a href="/article/1949459858382188544.htm" title="你的一个箭头函数让我找了几天" target="_blank">你的一个箭头函数让我找了几天</a> <span class="text-muted">JsLin_</span> <div>同事的h5的相关内容给我接手了,上线后发现好多手机浏览器不显示内容,就是这个问题断断续续找了有两个星期的时间,迫使我把他的h5相关的内容用react重构了一遍,重构完又发现一大堆事情。先抱怨下吧首先,一个网站的域名竟然不指定首页?大图片资源不压缩?找了一段时间,没找到原因,迫使我把它的代码用react重构了,也正好练练手。重构完了之后,发现运维那里的以前的工程nginx部署没有指定主页,才发现官网</div> </li> <li><a href="/article/1949397350233468928.htm" title="前端“武林”争“盟主”?我有我的看法!" target="_blank">前端“武林”争“盟主”?我有我的看法!</a> <span class="text-muted">秋风_bdfd</span> <div>了解过web前端的都知道前端的三大框架,这也是前端攻城狮们向来争论的话题。下面就由小编来发表一下自己的一点小小的看法,如有别的看法,轻喷~前端这三大框架的争议那么大,就是因为使用的人太多了。对于小白来说,一开始接触前端,学习的都是HTML、CSS、JS。但是你学完这3样之后,你还得深入的往后期学,那么要学什么呢?当然就是我们今天所说的框架啦。因为在实际工作中,基本都是直接在框架上构建网站的,很少会</div> </li> <li><a href="/article/1949392722615922688.htm" title="面试复盘:为什么Vue2的data数据量大时内存开销大?" target="_blank">面试复盘:为什么Vue2的data数据量大时内存开销大?</a> <span class="text-muted">neon1204</span> <a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF%E9%9D%A2%E8%AF%95/1.htm">前端面试</a><a class="tag" taget="_blank" href="/search/%E9%9D%A2%E8%AF%95/1.htm">面试</a><a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a><a class="tag" taget="_blank" href="/search/javascript/1.htm">javascript</a><a class="tag" taget="_blank" href="/search/vue.js/1.htm">vue.js</a> <div>背景描述今天前端技术面试中,面试官针对Vue2的源码和性能方面提问:“当data中存储大量数据时,为什么内存开销显著增加?”。本文复盘梳理我的回答思路:一、核心机制:Object.defineProperty的递归与闭包Vue2的响应式系统通过递归遍历data中的每个属性,将其转换为getter/setter。这一过程在源码中由defineReactive函数实现,其内存开销主要来自以下三点:1.</div> </li> <li><a href="/article/1949327524823625728.htm" title="React入门指南——指北指南(第二节)" target="_blank">React入门指南——指北指南(第二节)</a> <span class="text-muted">逢着</span> <a class="tag" taget="_blank" href="/search/react.js/1.htm">react.js</a><a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a><a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF%E6%A1%86%E6%9E%B6/1.htm">前端框架</a> <div>React实践:创建你的第一个待办事项列表在前面的章节中,我们学习了React的核心概念(组件、Props、State等)。本节将通过一个实际案例——创建待办事项列表(TodoList),帮助你巩固这些概念,并掌握React中处理用户交互、动态数据的基本方法。案例目标我们将构建一个简单但功能完整的待办事项应用,包含以下功能:输入框中输入文本,点击按钮添加新的待办项;显示所有待办项的列表;点击单个待</div> </li> <li><a href="/article/1949327525301776384.htm" title="React入门学习——指北指南(第三节)" target="_blank">React入门学习——指北指南(第三节)</a> <span class="text-muted">逢着</span> <a class="tag" taget="_blank" href="/search/react.js/1.htm">react.js</a><a class="tag" taget="_blank" href="/search/%E5%AD%A6%E4%B9%A0/1.htm">学习</a><a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a> <div>React组件在前面的内容中,我们了解了React的基础知识和入门案例。本节将深入探讨React中最核心的概念之一——组件。组件是构建React应用的基础,理解组件的工作原理和使用方法,对于掌握React开发至关重要。什么是组件?在React中,组件是具有独立功能和UI的可复用代码块。可以将组件看作是构建用户界面的“积木”,通过组合不同的组件,能够搭建出复杂的页面。组件就像一个函数,它可以接收输入</div> </li> <li><a href="/article/1949301425460801536.htm" title="Java面试题及详细答案120道之(041-060)" target="_blank">Java面试题及详细答案120道之(041-060)</a> <span class="text-muted">还是大剑师兰特</span> <a class="tag" taget="_blank" href="/search/%E5%89%8D%E5%90%8E%E7%AB%AF%E9%9D%A2%E8%AF%95%E9%A2%98/1.htm">前后端面试题</a><a class="tag" taget="_blank" href="/search/%E5%A4%A7%E5%89%91%E5%B8%88/1.htm">大剑师</a><a class="tag" taget="_blank" href="/search/java%E9%9D%A2%E8%AF%95%E9%A2%98/1.htm">java面试题</a> <div>《前后端面试题》专栏集合了前后端各个知识模块的面试题,包括html,javascript,css,vue,react,java,Openlayers,leaflet,cesium,mapboxGL,threejs,nodejs,mangoDB,MySQL,Linux…。前后端面试题-专栏总目录文章目录一、本文面试题目录41.什么是工厂模式?简单工厂、工厂方法、抽象工厂的区别?42.Java中的泛型</div> </li> <li><a href="/article/1949256916337225728.htm" title="快速梳理遗留项目" target="_blank">快速梳理遗留项目</a> <span class="text-muted">lixzest</span> <a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/c%2B%2B/1.htm">c++</a> <div>梳理一个别人写的代码项目是开发者常遇到的任务,尤其是接手遗留项目或团队协作时。以下是系统化的步骤和技巧,帮助快速理解项目结构和逻辑:1.了解项目背景项目目标:与产品经理或前任开发者沟通,明确项目用途(如电商系统、数据分析工具等)。技术栈:确认语言(Python/Java/Go等)、框架(Spring/Django/React等)、数据库(MySQL/MongoDB等)。文档检查:优先阅读READM</div> </li> <li><a href="/article/1949236611715756032.htm" title="如何实现零成本裂变?微信推客带货小程序开发功能模式全解析" target="_blank">如何实现零成本裂变?微信推客带货小程序开发功能模式全解析</a> <span class="text-muted">开发加微信:hedian116</span> <a class="tag" taget="_blank" href="/search/%E5%BE%AE%E4%BF%A1/1.htm">微信</a> <div>引言在当今社交电商蓬勃发展的背景下,微信推客系统作为一种基于社交关系的分销模式,其技术实现和架构设计值得开发者深入探讨。本文将从技术角度分析微信推客系统的核心组件和实现原理,避免商业营销,专注于技术层面的分享。一、微信推客系统的基本架构1.1前端架构微信推客系统通常采用混合开发模式:小程序前端:使用WXML+WXSS+JavaScript技术栈H5页面:Vue.js或React框架实现跨平台兼容原</div> </li> <li><a href="/article/1949230177275932672.htm" title="【自动化测试】web前端组件测试范围梳理" target="_blank">【自动化测试】web前端组件测试范围梳理</a> <span class="text-muted">阿槿吃糖</span> <a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF%E8%87%AA%E5%8A%A8%E5%8C%96%E6%B5%8B%E8%AF%95/1.htm">前端自动化测试</a><a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a> <div>测试组件范围划分按钮文字链接单选框多选框输入框计数器选择器级联选择器开关日期选择器上传分页弹窗导航菜单表格富文本编辑器前端组件测试范围梳理-png</div> </li> <li><a href="/article/1949208866151526400.htm" title="React Native启动android报错 Failed to install the app. Command failed with exit code 1: gradlew.b(亲测有效)" target="_blank">React Native启动android报错 Failed to install the app. Command failed with exit code 1: gradlew.b(亲测有效)</a> <span class="text-muted">安心不心安</span> <a class="tag" taget="_blank" href="/search/React/1.htm">React</a><a class="tag" taget="_blank" href="/search/Native%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/1.htm">Native学习笔记</a><a class="tag" taget="_blank" href="/search/react/1.htm">react</a><a class="tag" taget="_blank" href="/search/native/1.htm">native</a><a class="tag" taget="_blank" href="/search/android/1.htm">android</a><a class="tag" taget="_blank" href="/search/react.js/1.htm">react.js</a> <div>一、原因react-nativerun-android或npxreact-nativestart命令的默认行为是:编译APK(通过Gradle)。安装APK到设备(通过adbinstall)。启动应用(通过adbshellamstart)。如果模拟器未提前启动:adb可能找不到设备,导致安装步骤失败。错误可能表现为Noconnecteddevices!或INSTALL_FAILED。二、解决方法注</div> </li> <li><a href="/article/1949198772189851648.htm" title="算法在前端框架中的集成" target="_blank">算法在前端框架中的集成</a> <span class="text-muted"></span> <div>引言算法是前端开发中提升性能和用户体验的重要工具。随着Web应用复杂性的增加,现代前端框架如React、Vue和Angular提供了强大的工具集,使得将算法与框架特性(如状态管理、虚拟DOM和组件化)无缝集成成为可能。从排序算法优化列表渲染到动态规划提升复杂计算效率,算法的集成能够显著改善应用的响应速度和资源利用率。本文将探讨如何将常见算法(排序、搜索和动态规划)集成到前端框架中,重点介绍框架特性</div> </li> <li><a href="/article/30.htm" title="Java实现的基于模板的网页结构化信息精准抽取组件:HtmlExtractor" target="_blank">Java实现的基于模板的网页结构化信息精准抽取组件:HtmlExtractor</a> <span class="text-muted">yangshangchuan</span> <a class="tag" taget="_blank" href="/search/%E4%BF%A1%E6%81%AF%E6%8A%BD%E5%8F%96/1.htm">信息抽取</a><a class="tag" taget="_blank" href="/search/HtmlExtractor/1.htm">HtmlExtractor</a><a class="tag" taget="_blank" href="/search/%E7%B2%BE%E5%87%86%E6%8A%BD%E5%8F%96/1.htm">精准抽取</a><a class="tag" taget="_blank" href="/search/%E4%BF%A1%E6%81%AF%E9%87%87%E9%9B%86/1.htm">信息采集</a> <div>HtmlExtractor是一个Java实现的基于模板的网页结构化信息精准抽取组件,本身并不包含爬虫功能,但可被爬虫或其他程序调用以便更精准地对网页结构化信息进行抽取。   HtmlExtractor是为大规模分布式环境设计的,采用主从架构,主节点负责维护抽取规则,从节点向主节点请求抽取规则,当抽取规则发生变化,主节点主动通知从节点,从而能实现抽取规则变化之后的实时动态生效。 如</div> </li> <li><a href="/article/157.htm" title="java编程思想 -- 多态" target="_blank">java编程思想 -- 多态</a> <span class="text-muted">百合不是茶</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E5%A4%9A%E6%80%81%E8%AF%A6%E8%A7%A3/1.htm">多态详解</a> <div>一: 向上转型和向下转型 面向对象中的转型只会发生在有继承关系的子类和父类中(接口的实现也包括在这里)。父类:人    子类:男人向上转型: Person p = new Man() ; //向上转型不需要强制类型转化向下转型: Man man =</div> </li> <li><a href="/article/284.htm" title="[自动数据处理]稳扎稳打,逐步形成自有ADP系统体系" target="_blank">[自动数据处理]稳扎稳打,逐步形成自有ADP系统体系</a> <span class="text-muted">comsci</span> <a class="tag" taget="_blank" href="/search/dp/1.htm">dp</a> <div>       对于国内的IT行业来讲,虽然我们已经有了"两弹一星",在局部领域形成了自己独有的技术特征,并初步摆脱了国外的控制...但是前面的路还很长....       首先是我们的自动数据处理系统还无法处理很多高级工程...中等规模的拓扑分析系统也没有完成,更加复杂的</div> </li> <li><a href="/article/411.htm" title="storm 自定义 日志文件" target="_blank">storm 自定义 日志文件</a> <span class="text-muted">商人shang</span> <a class="tag" taget="_blank" href="/search/storm/1.htm">storm</a><a class="tag" taget="_blank" href="/search/cluster/1.htm">cluster</a><a class="tag" taget="_blank" href="/search/logback/1.htm">logback</a> <div>Storm中的日志级级别默认为INFO,并且,日志文件是根据worker号来进行区分的,这样,同一个log文件中的信息不一定是一个业务的,这样就会有以下两个需求出现: 1. 想要进行一些调试信息的输出 2. 调试信息或者业务日志信息想要输出到一些固定的文件中   不要怕,不要烦恼,其实Storm已经提供了这样的支持,可以通过自定义logback 下的 cluster.xml 来输</div> </li> <li><a href="/article/538.htm" title="Extjs3 SpringMVC使用 @RequestBody 标签问题记录" target="_blank">Extjs3 SpringMVC使用 @RequestBody 标签问题记录</a> <span class="text-muted">21jhf</span> <div>springMVC使用 @RequestBody(required = false) UserVO userInfo 传递json对象数据,往往会出现http 415,400,500等错误,总结一下需要使用ajax提交json数据才行,ajax提交使用proxy,参数为jsonData,不能为params;另外,需要设置Content-type属性为json,代码如下: (由于使用了父类aaa</div> </li> <li><a href="/article/665.htm" title="一些排错方法" target="_blank">一些排错方法</a> <span class="text-muted">文强chu</span> <a class="tag" taget="_blank" href="/search/%E6%96%B9%E6%B3%95/1.htm">方法</a> <div>1、java.lang.IllegalStateException: Class invariant violation at org.apache.log4j.LogManager.getLoggerRepository(LogManager.java:199)at org.apache.log4j.LogManager.getLogger(LogManager.java:228) at o</div> </li> <li><a href="/article/792.htm" title="Swing中文件恢复我觉得很难" target="_blank">Swing中文件恢复我觉得很难</a> <span class="text-muted">小桔子</span> <a class="tag" taget="_blank" href="/search/swing/1.htm">swing</a> <div>       我那个草了!老大怎么回事,怎么做项目评估的?只会说相信你可以做的,试一下,有的是时间!        用java开发一个图文处理工具,类似word,任意位置插入、拖动、删除图片以及文本等。文本框、流程图等,数据保存数据库,其余可保存pdf格式。ok,姐姐千辛万苦,</div> </li> <li><a href="/article/919.htm" title="php 文件操作" target="_blank">php 文件操作</a> <span class="text-muted">aichenglong</span> <a class="tag" taget="_blank" href="/search/PHP/1.htm">PHP</a><a class="tag" taget="_blank" href="/search/%E8%AF%BB%E5%8F%96%E6%96%87%E4%BB%B6/1.htm">读取文件</a><a class="tag" taget="_blank" href="/search/%E5%86%99%E5%85%A5%E6%96%87%E4%BB%B6/1.htm">写入文件</a> <div>1 写入文件 @$fp=fopen("$DOCUMENT_ROOT/order.txt", "ab"); if(!$fp){ echo "open file error" ; exit; } $outputstring="date:"." \t tire:".$tire."</div> </li> <li><a href="/article/1046.htm" title="MySQL的btree索引和hash索引的区别" target="_blank">MySQL的btree索引和hash索引的区别</a> <span class="text-muted">AILIKES</span> <a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/1.htm">数据结构</a><a class="tag" taget="_blank" href="/search/mysql/1.htm">mysql</a><a class="tag" taget="_blank" href="/search/%E7%AE%97%E6%B3%95/1.htm">算法</a> <div>Hash 索引结构的特殊性,其 检索效率非常高,索引的检索可以一次定位,不像B-Tree 索引需要从根节点到枝节点,最后才能访问到页节点这样多次的IO访问,所以 Hash 索引的查询效率要远高于 B-Tree 索引。     可能很多人又有疑问了,既然 Hash 索引的效率要比 B-Tree 高很多,为什么大家不都用 Hash 索引而还要使用 B-Tree 索引呢</div> </li> <li><a href="/article/1173.htm" title="JAVA的抽象--- 接口 --实现" target="_blank">JAVA的抽象--- 接口 --实现</a> <span class="text-muted">百合不是茶</span> <div>抽象 接口 实现接口   //抽象 类 ,方法   //定义一个公共抽象的类 ,并在类中定义一个抽象的方法体 抽象的定义使用abstract   abstract class A 定义一个抽象类 例如: //定义一个基类 public abstract class A{     //抽象类不能用来实例化,只能用来继承 //</div> </li> <li><a href="/article/1300.htm" title="JS变量作用域实例" target="_blank">JS变量作用域实例</a> <span class="text-muted">bijian1013</span> <a class="tag" taget="_blank" href="/search/%E4%BD%9C%E7%94%A8%E5%9F%9F/1.htm">作用域</a> <div><script> var scope='hello'; function a(){ console.log(scope); //undefined var scope='world'; console.log(scope); //world console.log(b); </div> </li> <li><a href="/article/1427.htm" title="TDD实践(二)" target="_blank">TDD实践(二)</a> <span class="text-muted">bijian1013</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/TDD/1.htm">TDD</a> <div>实践题目:分解质因数 Step1: 单元测试: package com.bijian.study.factor.test; import java.util.Arrays; import junit.framework.Assert; import org.junit.Before; import org.junit.Test; import com.bijian.</div> </li> <li><a href="/article/1554.htm" title="[MongoDB学习笔记一]MongoDB主从复制" target="_blank">[MongoDB学习笔记一]MongoDB主从复制</a> <span class="text-muted">bit1129</span> <a class="tag" taget="_blank" href="/search/mongodb/1.htm">mongodb</a> <div>MongoDB称为分布式数据库,主要原因是1.基于副本集的数据备份, 2.基于切片的数据扩容。副本集解决数据的读写性能问题,切片解决了MongoDB的数据扩容问题。   事实上,MongoDB提供了主从复制和副本复制两种备份方式,在MongoDB的主从复制和副本复制集群环境中,只有一台作为主服务器,另外一台或者多台服务器作为从服务器。 本文介绍MongoDB的主从复制模式,需要指明</div> </li> <li><a href="/article/1681.htm" title="【HBase五】Java API操作HBase" target="_blank">【HBase五】Java API操作HBase</a> <span class="text-muted">bit1129</span> <a class="tag" taget="_blank" href="/search/hbase/1.htm">hbase</a> <div>import java.io.IOException; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.HBaseConfiguration; import org.apache.hadoop.hbase.HColumnDescriptor; import org.apache.ha</div> </li> <li><a href="/article/1808.htm" title="python调用zabbix api接口实时展示数据" target="_blank">python调用zabbix api接口实时展示数据</a> <span class="text-muted">ronin47</span> <div>zabbix api接口来进行展示。经过思考之后,计划获取如下内容:     1、  获得认证密钥     2、  获取zabbix所有的主机组     3、  获取单个组下的所有主机     4、  获取某个主机下的所有监控项  </div> </li> <li><a href="/article/1935.htm" title="jsp取得绝对路径" target="_blank">jsp取得绝对路径</a> <span class="text-muted">byalias</span> <a class="tag" taget="_blank" href="/search/%E7%BB%9D%E5%AF%B9%E8%B7%AF%E5%BE%84/1.htm">绝对路径</a> <div>在JavaWeb开发中,常使用绝对路径的方式来引入JavaScript和CSS文件,这样可以避免因为目录变动导致引入文件找不到的情况,常用的做法如下: 一、使用${pageContext.request.contextPath}   代码” ${pageContext.request.contextPath}”的作用是取出部署的应用程序名,这样不管如何部署,所用路径都是正确的。 </div> </li> <li><a href="/article/2062.htm" title="Java定时任务调度:用ExecutorService取代Timer" target="_blank">Java定时任务调度:用ExecutorService取代Timer</a> <span class="text-muted">bylijinnan</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a> <div>《Java并发编程实战》一书提到的用ExecutorService取代Java Timer有几个理由,我认为其中最重要的理由是: 如果TimerTask抛出未检查的异常,Timer将会产生无法预料的行为。Timer线程并不捕获异常,所以 TimerTask抛出的未检查的异常会终止timer线程。这种情况下,Timer也不会再重新恢复线程的执行了;它错误的认为整个Timer都被取消了。此时,已经被</div> </li> <li><a href="/article/2189.htm" title="SQL 优化原则" target="_blank">SQL 优化原则</a> <span class="text-muted">chicony</span> <a class="tag" taget="_blank" href="/search/sql/1.htm">sql</a> <div> 一、问题的提出  在应用系统开发初期,由于开发数据库数据比较少,对于查询SQL语句,复杂视图的的编写等体会不出SQL语句各种写法的性能优劣,但是如果将应用系统提交实际应用后,随着数据库中数据的增加,系统的响应速度就成为目前系统需要解决的最主要的问题之一。系统优化中一个很重要的方面就是SQL语句的优化。对于海量数据,劣质SQL语句和优质SQL语句之间的速度差别可以达到上百倍,可见对于一个系统</div> </li> <li><a href="/article/2316.htm" title="java 线程弹球小游戏" target="_blank">java 线程弹球小游戏</a> <span class="text-muted">CrazyMizzz</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E6%B8%B8%E6%88%8F/1.htm">游戏</a> <div>最近java学到线程,于是做了一个线程弹球的小游戏,不过还没完善 这里是提纲 1.线程弹球游戏实现 1.实现界面需要使用哪些API类 JFrame JPanel JButton FlowLayout Graphics2D Thread Color ActionListener ActionEvent MouseListener Mouse</div> </li> <li><a href="/article/2443.htm" title="hadoop jps出现process information unavailable提示解决办法" target="_blank">hadoop jps出现process information unavailable提示解决办法</a> <span class="text-muted">daizj</span> <a class="tag" taget="_blank" href="/search/hadoop/1.htm">hadoop</a><a class="tag" taget="_blank" href="/search/jps/1.htm">jps</a> <div>hadoop jps出现process information unavailable提示解决办法   jps时出现如下信息: 3019 -- process information unavailable3053 -- process information unavailable2985 -- process information unavailable2917 -- </div> </li> <li><a href="/article/2570.htm" title="PHP图片水印缩放类实现" target="_blank">PHP图片水印缩放类实现</a> <span class="text-muted">dcj3sjt126com</span> <a class="tag" taget="_blank" href="/search/PHP/1.htm">PHP</a> <div> <?php class Image{ private $path; function __construct($path='./'){ $this->path=rtrim($path,'/').'/'; } //水印函数,参数:背景图,水印图,位置,前缀,TMD透明度 public function water($b,$l,$pos</div> </li> <li><a href="/article/2697.htm" title="IOS控件学习:UILabel常用属性与用法" target="_blank">IOS控件学习:UILabel常用属性与用法</a> <span class="text-muted">dcj3sjt126com</span> <a class="tag" taget="_blank" href="/search/ios/1.htm">ios</a><a class="tag" taget="_blank" href="/search/UILabel/1.htm">UILabel</a> <div>参考网站: http://shijue.me/show_text/521c396a8ddf876566000007 http://www.tuicool.com/articles/zquENb http://blog.csdn.net/a451493485/article/details/9454695 http://wiki.eoe.cn/page/iOS_pptl_artile_281</div> </li> <li><a href="/article/2824.htm" title="完全手动建立maven骨架" target="_blank">完全手动建立maven骨架</a> <span class="text-muted">eksliang</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/eclipse/1.htm">eclipse</a><a class="tag" taget="_blank" href="/search/Web/1.htm">Web</a> <div>建一个 JAVA 项目 : mvn archetype:create -DgroupId=com.demo -DartifactId=App [-Dversion=0.0.1-SNAPSHOT] [-Dpackaging=jar] 建一个 web 项目 : mvn archetype:create -DgroupId=com.demo -DartifactId=web-a</div> </li> <li><a href="/article/2951.htm" title="配置清单" target="_blank">配置清单</a> <span class="text-muted">gengzg</span> <a class="tag" taget="_blank" href="/search/%E9%85%8D%E7%BD%AE/1.htm">配置</a> <div>1、修改grub启动的内核版本 vi /boot/grub/grub.conf 将default 0改为1 拷贝mt7601Usta.ko到/lib文件夹 拷贝RT2870STA.dat到 /etc/Wireless/RT2870STA/文件夹 拷贝wifiscan到bin文件夹,chmod 775 /bin/wifiscan 拷贝wifiget.sh到bin文件夹,chm</div> </li> <li><a href="/article/3078.htm" title="Windows端口被占用处理方法" target="_blank">Windows端口被占用处理方法</a> <span class="text-muted">huqiji</span> <a class="tag" taget="_blank" href="/search/windows/1.htm">windows</a> <div>以下文章主要以80端口号为例,如果想知道其他的端口号也可以使用该方法..........................1、在windows下如何查看80端口占用情况?是被哪个进程占用?如何终止等.        这里主要是用到windows下的DOS工具,点击"开始"--"运行",输入&</div> </li> <li><a href="/article/3205.htm" title="开源ckplayer 网页播放器, 跨平台(html5, mobile),flv, f4v, mp4, rtmp协议. webm, ogg, m3u8 !" target="_blank">开源ckplayer 网页播放器, 跨平台(html5, mobile),flv, f4v, mp4, rtmp协议. webm, ogg, m3u8 !</a> <span class="text-muted">天梯梦</span> <a class="tag" taget="_blank" href="/search/mobile/1.htm">mobile</a> <div>CKplayer,其全称为超酷flv播放器,它是一款用于网页上播放视频的软件,支持的格式有:http协议上的flv,f4v,mp4格式,同时支持rtmp视频流格 式播放,此播放器的特点在于用户可以自己定义播放器的风格,诸如播放/暂停按钮,静音按钮,全屏按钮都是以外部图片接口形式调用,用户根据自己的需要制作 出播放器风格所需要使用的各个按钮图片然后替换掉原始风格里相应的图片就可以制作出自己的风格了,</div> </li> <li><a href="/article/3332.htm" title="简单工厂设计模式" target="_blank">简单工厂设计模式</a> <span class="text-muted">hm4123660</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E5%B7%A5%E5%8E%82%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/1.htm">工厂设计模式</a><a class="tag" taget="_blank" href="/search/%E7%AE%80%E5%8D%95%E5%B7%A5%E5%8E%82%E6%A8%A1%E5%BC%8F/1.htm">简单工厂模式</a> <div>       简单工厂模式(Simple Factory Pattern)属于类的创新型模式,又叫静态工厂方法模式。是通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现。 </div> </li> <li><a href="/article/3459.htm" title="maven笔记" target="_blank">maven笔记</a> <span class="text-muted">zhb8015</span> <a class="tag" taget="_blank" href="/search/maven/1.htm">maven</a> <div>跳过测试阶段: mvn package -DskipTests 临时性跳过测试代码的编译: mvn package -Dmaven.test.skip=true   maven.test.skip同时控制maven-compiler-plugin和maven-surefire-plugin两个插件的行为,即跳过编译,又跳过测试。   指定测试类 mvn test</div> </li> <li><a href="/article/3586.htm" title="非mapreduce生成Hfile,然后导入hbase当中" target="_blank">非mapreduce生成Hfile,然后导入hbase当中</a> <span class="text-muted">Stark_Summer</span> <a class="tag" taget="_blank" href="/search/map/1.htm">map</a><a class="tag" taget="_blank" href="/search/hbase/1.htm">hbase</a><a class="tag" taget="_blank" href="/search/reduce/1.htm">reduce</a><a class="tag" taget="_blank" href="/search/Hfile/1.htm">Hfile</a><a class="tag" taget="_blank" href="/search/path%E5%AE%9E%E4%BE%8B/1.htm">path实例</a> <div>最近一个群友的boss让研究hbase,让hbase的入库速度达到5w+/s,这可愁死了,4台个人电脑组成的集群,多线程入库调了好久,速度也才1w左右,都没有达到理想的那种速度,然后就想到了这种方式,但是网上多是用mapreduce来实现入库,而现在的需求是实时入库,不生成文件了,所以就只能自己用代码实现了,但是网上查了很多资料都没有查到,最后在一个网友的指引下,看了源码,最后找到了生成Hfile</div> </li> <li><a href="/article/3713.htm" title="jsp web tomcat 编码问题" target="_blank">jsp web tomcat 编码问题</a> <span class="text-muted">王新春</span> <a class="tag" taget="_blank" href="/search/tomcat/1.htm">tomcat</a><a class="tag" taget="_blank" href="/search/jsp/1.htm">jsp</a><a class="tag" taget="_blank" href="/search/pageEncode/1.htm">pageEncode</a> <div>今天配置jsp项目在tomcat上,windows上正常,而linux上显示乱码,最后定位原因为tomcat 的server.xml 文件的配置,添加 URIEncoding 属性: <Connector port="8080" protocol="HTTP/1.1" connectionTi</div> </li> </ul> </div> </div> </div> <div> <div class="container"> <div class="indexes"> <strong>按字母分类:</strong> <a href="/tags/A/1.htm" target="_blank">A</a><a href="/tags/B/1.htm" target="_blank">B</a><a href="/tags/C/1.htm" target="_blank">C</a><a href="/tags/D/1.htm" target="_blank">D</a><a href="/tags/E/1.htm" target="_blank">E</a><a href="/tags/F/1.htm" target="_blank">F</a><a href="/tags/G/1.htm" target="_blank">G</a><a href="/tags/H/1.htm" target="_blank">H</a><a href="/tags/I/1.htm" target="_blank">I</a><a href="/tags/J/1.htm" target="_blank">J</a><a href="/tags/K/1.htm" target="_blank">K</a><a href="/tags/L/1.htm" target="_blank">L</a><a href="/tags/M/1.htm" target="_blank">M</a><a href="/tags/N/1.htm" target="_blank">N</a><a href="/tags/O/1.htm" target="_blank">O</a><a href="/tags/P/1.htm" target="_blank">P</a><a href="/tags/Q/1.htm" target="_blank">Q</a><a href="/tags/R/1.htm" target="_blank">R</a><a href="/tags/S/1.htm" target="_blank">S</a><a href="/tags/T/1.htm" target="_blank">T</a><a href="/tags/U/1.htm" target="_blank">U</a><a href="/tags/V/1.htm" target="_blank">V</a><a href="/tags/W/1.htm" target="_blank">W</a><a href="/tags/X/1.htm" target="_blank">X</a><a href="/tags/Y/1.htm" target="_blank">Y</a><a href="/tags/Z/1.htm" target="_blank">Z</a><a href="/tags/0/1.htm" target="_blank">其他</a> </div> </div> </div> <footer id="footer" class="mb30 mt30"> <div class="container"> <div class="footBglm"> <a target="_blank" href="/">首页</a> - <a target="_blank" href="/custom/about.htm">关于我们</a> - <a target="_blank" href="/search/Java/1.htm">站内搜索</a> - <a target="_blank" href="/sitemap.txt">Sitemap</a> - <a target="_blank" href="/custom/delete.htm">侵权投诉</a> </div> <div class="copyright">版权所有 IT知识库 CopyRight © 2000-2050 E-COM-NET.COM , All Rights Reserved. <!-- <a href="https://beian.miit.gov.cn/" rel="nofollow" target="_blank">京ICP备09083238号</a><br>--> </div> </div> </footer> <!-- 代码高亮 --> <script type="text/javascript" src="/static/syntaxhighlighter/scripts/shCore.js"></script> <script type="text/javascript" src="/static/syntaxhighlighter/scripts/shLegacy.js"></script> <script type="text/javascript" src="/static/syntaxhighlighter/scripts/shAutoloader.js"></script> <link type="text/css" rel="stylesheet" href="/static/syntaxhighlighter/styles/shCoreDefault.css"/> <script type="text/javascript" src="/static/syntaxhighlighter/src/my_start_1.js"></script> </body> </html>