从零开始使用webpack(4.x)+bable+react+ant-design配置单页面应用开发环境(附模板)

从零开始使用webpack(4.x)+bable+react+ant-design配置单页面应用开发环境(附模板)

  • 前言
  • 一 准备工作
    • 1 建立项目目录
    • 2 安装webpack
    • 3 准备项目文件结构
  • 二 配置webpack的工作
    • 1 基础配置
    • 2 配置webpack-dev-server
  • 三 使用React开发页面
  • 四 使用Webpack、Babel和React开发页面
    • 1 安装react
    • 2 生成主入口文件
    • 3 生成我们的html
    • 4 引入Bable解析ES6语法和jsx
    • 5 使用Ant Design作为React的UI库
    • 6 使用webpack加载样式表
    • 7 配置按需加载
  • 五 其他配置
    • 1 使用less语法加载器
    • 2 在react中引用图片资源
    • 3 将样式表单独打包发布成css文件
  • 六 发布产品&配置产品环境
    • 1 打包发布时压缩css文件
    • 2 打包发布时压缩js文件
    • 3 资源文件夹优化
    • 4 关于调试代码(source-map)
  • 七 结语

前言

学习即进步。本人一直使用vue框架,对于react框架一直是得闻不如一见。在一些简单的网站学习了react框架的基本教程之后,参照本人一直使用的webpack+bable+vue+iview开发环境。对应着想搭建一个基于react的开发环境,借此来对比,看看到底是哪个框架比较好用,效率高。进过分析,比对,我选择了与react最为般配的ant-design作为前端ul框架。即模式确定为webpack+bable+react+ant-design;如果需要偷懒,可以直接下载我的github项目,开包即用。

一 准备工作

先挂一下我的package.json,小白可以先忽略。项目结束之后可以提供参考。注意 我使用的是webpack4.x的版本。与3.x的部分内容可能不兼容。

 "devDependencies": {
    "babel-core": "^6.26.0",
    "babel-loader": "^7.1.2",
    "babel-plugin-import": "^1.11.0",
    "babel-preset-env": "^1.6.1",
    "babel-preset-react": "^6.24.1",
    "babel-preset-stage-0": "^6.24.1",
    "css-loader": "^2.1.0",
    "file-loader": "^3.0.1",
    "html-webpack-plugin": "^3.2.0",
    "less": "^2.7.3",
    "less-loader": "^4.0.5",
    "mini-css-extract-plugin": "^0.5.0",
    "optimize-css-assets-webpack-plugin": "^5.0.1",
    "style-loader": "^0.23.1",
    "url-loader": "^1.1.2",
    "webpack": "^4.29.5",
    "webpack-cli": "^3.2.3",
    "webpack-dev-server": "^3.1.0",
    "webpack-merge": "^4.1.0",
    "uglifyjs-webpack-plugin": "^2.1.1"
  },
  "dependencies": {
    "react": "^16.0.0",
    "react-dom": "^16.0.0",
    "antd": "^3.13.5"
  }

1 建立项目目录

  • 新建项目文件夹E:\study\webpack 下面简写为 根目录
  • 命令行进入目录,使用npm init指令进行npm的初始化。按照提示依次键入信息,不知道的直接回车。

2 安装webpack

  • 不建议全局安装webpack
  • 局部安装webpack 根目录>cnpm i webpack --save-dev
  • 没有cnpm的话安装一下淘宝镜像,npm install -g cnpm --registry=https://registry.npm.taobao.org
  • 这时自动安装完毕。package.json中devDependencies自动添加了对webpack的依赖。
"devDependencies": {
  "webpack": "^4.0.0",
}

说明1: webpack版本只要是4之后都可以。我这里只是演示
说明2: devDependencies是开发依赖,只会在打包过程中用到,不会包含到最后的代码中
说明3: 如果想安装指定版本的webpack,使用npm install --save-dev webpack@<版本号>格式

3 准备项目文件结构

我们的项目需要脚本,html,样式,图片以及一些其他资源。

│   package.json
├───node_modules
│       └╌╌ 下面是npm包
├───build
│   ├╌╌╌╌╌ build.js
│   ├╌╌╌╌╌ webpack.base.conf.js
│   ├╌╌╌╌╌ webpack.dev.conf.js
│   └╌╌╌╌╌ webpack.prod.conf.js
├───src
│   ├╌╌╌╌╌ main.js
│   └╌╌╌╌╌template
│         └╌╌╌╌╌template.html // 首页的模板
│   └╌╌╌╌╌images
│         └╌╌╌╌╌logo.jpg  

对,暂时我们就准备这些。

二 配置webpack的工作

webpack的工作就一个。根据一个入口文件,通过import,require等建立目标文件之间的关联关系,调用对应文件后缀的loader实现按需加载。有关完整的配置,可以参考我的下一篇文章。我们今天讲的,都是基本的配置。

1 基础配置

首先我们配置文件,打开webpack.base.conf.js,填写如下内容。

module.exports = {
    entry: './src/main', //main.js中的.js可以省略,前面的./不能省
}

有些朋友也许会问,build目录下有那么多js。为什么是webpack.base.conf.js。

首先,我们知道开发一个项目。有开发阶段和打包发布阶段,所以webpack的工作配置,也分为dev(开发)阶段配置和prod(发布产品)配置。开发模式与产品模式的webpack配置最主要的区别就是开发时需要一个热更新的服务器。以便于我们写的代码能够保存一次就能看到最新效果。而发布之后就是生成静态html文件,由产品服务器托管了。还有很多其他的区别,在之后我们会一一讲到。但是,大部分的基本配置都是一样的,所以我们分了3个文件,webpack.base.conf.js中是webpack通用的配置组成,例如入口文件,这绝对是通用的部分。然后我们再把区分的配置分别写到webpack.dev.conf.jswebpack.prod.conf.js中,再通过webpack-merge去合并配置。

package.json中配置webpack的调用方式,在script标签栏内填入

  "scripts": {
    "build": "webpack --config ./build/webpack.prod.conf.js",
    "dev": "webpack-dev-server --config ./build/webpack.dev.conf.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },

理所当然的,我们现在分成了两个指令:build负责打包生成产品文件,dev负责搭建热更新服务器,实时调试我们的代码。

所以,我们在webpack.dev.conf.js中配webpack-dev-server服务器。

2 配置webpack-dev-server

在这里说明一下,为了保证大家安装的包版本跟我一致,安装依赖包的方式为直接在devDependencies中添加相关的版本,然后再调用cnpm install.

找到package.json添加依赖项

 "webpack-dev-server": "^3.1.0",
 "webpack-cli": "^3.2.3"

注意。webpack-dev-server依赖了"webpack-cli中的相关内容,所以也需要添加依赖。

根目录下执行cnpm install.

完成之后,在webpack.dev.conf.js中填入如下内容

const path = require('path');
const merge = require('webpack-merge');
const baseWebpackConfig = require('./webpack.base.conf')
module.exports = merge(baseWebpackConfig, {
    devtool: 'cheap-module-eval-source-map',
    output: {
        filename: './dist/[hash]app.js', // dist文件夹不存在时,会自动创建
        hashDigestLength: 8 // 默认长度是20
    },
    devServer: {
        contentBase: path.join(__dirname, "../dist"), //网站的根目录为 根目录/dist,如果配置不对,会报Cannot GET /错误
        port: 9000, //端口改为9000
        open: true// 自动打开浏览器,适合懒人
    },
})

webpack-merge也是webpack的库,需要单独安装
找到package.json添加依赖项

 "webpack-merge": "^4.1.0"

根目录下执行cnpm install.

  • webpack.dev.conf.js中通过引用webpack.base.conf.js,再通过merge对比,有的继承,没有的覆盖,这样就实现了公用基础配置的方法。
  • devtool : cheap-module-eval-source-map, devtool的配置比较复杂。这里你们先这样填,表示我可以在dev模式下F12 定位到原始文件debug我的代码。
  • output其实也是webpack基本配置。配置了项目打包生成的文件的存放处。由于我的dev模式和prod模式不一样,所以写在了dev的配置环境下。
  • devserver的配置参数我已经注释了。

好了。现阶段用于dev模式的webpack已经配置好了,接下来我们就可以开始编写我们的应用了。

三 使用React开发页面

使用React框架编写页面的方法有两种,第一种是直接在html文件中直接引用react.js和react-dom.js,然后在后续的脚本中使用React带来的能力。

一个普通的html文件便可以做到。


  
    
    
  
  
    

Hello world

但是这并不能很好的发挥react的作用。我们要使用ES6、JSX、UI重用等特性,因此我们将使用下面的第二种方法。

四 使用Webpack、Babel和React开发页面

1 安装react

react是我们项目运行时需要用到的包,所以我们需要在package.json中添加依赖项。react最终会被打包进我们的app.js中,供应用程序运行。安装单页面react运行环境目前需要2个包 reactreact-dom。我这里安装的是16.x的react(为了适配之后提到的antd):

//--package.json
"dependencies": {
    "react": "^16.0.0",
    "react-dom": "^16.0.0"
  },

然后在根目录cnpm install;

2 生成主入口文件

react安装好了。接下来我们就可以使用它了。在我们上面建立好的src/main.js中填入按照上面的js修改后的如下内容:

//--main.js
import React from 'react';
import ReactDOM from 'react-dom';
var e = React.createElement('p', null, 'This is React');
ReactDOM.render(e, document.getElementById('main'));

这里我们引用了npm包中安装的react和react-dom。仔细一看,

ReactDOM.render(e, document.getElementById('main'));

噢、看来我们至少需要一个html作为父容器,毕竟没有dom,脚本不可能正常运行。

到这里我们发现,react跟Vue一样,需要一个html页面作为最大的容器,所有的内容最后都会被webpack各种loader编译为浏览器可执行的文件,放到html中。

3 生成我们的html

这时候我们就需要webpack的一个插件html-webpack-plugin,来生成html。首先我们需要安装他。这是在项目编译打包阶段需要使用的库,所以我们把他放在devDependencies中。

//--package.json
"devDependencies": {
    "webpack": "^4.0.0",
    "webpack-cli": "^3.2.3",
    "webpack-dev-server": "^3.1.0",
    "webpack-merge": "^4.1.0",
    "html-webpack-plugin": "^3.2.0",
  }

根目录执行cnpm install.

接下来我们要使用它。这个配置属于通用的基础配置,所以我们继续打开刚才的基础配置文件webpack.base.conf.js,添加如下语句

//--webpack.base.conf.js
const HtmlWebpackPlugin = require('html-webpack-plugin'); //先引入
module.exports = {
    entry: './src/main', //main.js中的.js可以省略,前面的./不能省
    plugins: [
        new HtmlWebpackPlugin()
    ]
}

现在服务器也好了这样我们应该就可以跑着看了。我们在根目录执行npm run dev,没错,由于我们对于webpack-dev-server的配置open:true,在执行完毕之后我们就可以看到自动打开了浏览器,访问了我们配置的9000端口。

当然我们发现我们的浏览器一片空白

我们打开F12调试工具,先不管报的那个错误。我们去source栏查看,发现webpack确实已经帮我们根据入口main.js打包好了能运行的html。dist中是我们打包生成的app.js,并且已经根据我们配置在webpack.dev.conf.js中的输出,即加上8位哈希值相匹配。但是这些文件都是在内存中生成的,本地并不能找到。生成的html中在body标签的下方引用了生成的js。

从零开始使用webpack(4.x)+bable+react+ant-design配置单页面应用开发环境(附模板)_第1张图片

可以点开那个app.js查看一下。发现内部有我们配置在dependencies中的react已经被打包进去了。
从零开始使用webpack(4.x)+bable+react+ant-design配置单页面应用开发环境(附模板)_第2张图片
但是,我们在main.js中的代码引用了html中的元素。然而这个html是webpack自动生成的。所以我们需要修改html-webpack-plugin的配置,用我们自己的html作为模板。

  • 打开webpack.base.conf.js添加对于HtmlWebpackPlugin的配置。关于配置的详解我已经注释。
const HtmlWebpackPlugin = require('html-webpack-plugin'); //第二步导入
module.exports = {
    entry: './src/main', //main.js中的.js可以省略,前面的./不能省
    plugins: [
        new HtmlWebpackPlugin(
            {
                title: 'SEIE5.0', // html5文件中部分
                filename: 'index.html', // 默认是index.html,服务器中设置的首页是index.html,如果这里改成其它名字,那么devServer.index改为和它一样,最终完整文件路径是output.path+filename,如果filename中有子文件夹形式,如`./ab/cd/front.html`,只取`./front.html`
                template: './src/template/template.html', //如果觉得插件默认生成的hmtl5文件不合要求,可以指定一个模板,模板文件如果不存在,会报错,默认是在项目根目录下找模板文件,才模板为样板,将打包的js文件注入到body结尾处
                inject: "body", // true|body|head|false,四种值,默认为true,true和body相同,是将js注入到body结束标签前,head将打包的js文件放在head结束前,false是不注入,这时得要手工在html中加js
            }
        )
    ]
}
</code></pre> 
  <ul> 
   <li>打开<code>src/template/template.html</code>添加如下内容:</li> 
  </ul> 
  <pre><code><html>
  <body>
    <p>Hello world</p>
    <div id='main'/>
    
  </body>
</html>
</code></pre> 
  <p>ok 现在我们已经配置了让webpack按照我们给定的模板作为根容器了。现在我们重新运行<code>npm run dev</code></p> 
  <p><a href="http://img.e-com-net.com/image/info8/9c21eca5bc1f42ce85880e646b177094.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/9c21eca5bc1f42ce85880e646b177094.jpg" alt="从零开始使用webpack(4.x)+bable+react+ant-design配置单页面应用开发环境(附模板)_第3张图片" width="650" height="195" style="border:1px solid black;"></a></p> 
  <p>没错,已经完成了。现在react能够正常运行了。</p> 
  <blockquote> 
   <p>注意。inject配置的注入一定要在body。如果填写了head的话,react会报一个错误。找不到dom元素。因为加载react的时候,dom还未初始化完毕。</p> 
  </blockquote> 
  <h2>4 引入Bable解析ES6语法和jsx</h2> 
  <p>到这里,你会发现不需要使用Babel,我们就可以使用React开发页面内容了。但是你会注意到,除了import语句是webpack做了兼容性处理的,我所使用的其他语法都是ES5的语法。<br> 如果在main.js中使用JSX语法,webpack构建的时候就会报错。同样地,如果在main.js中添加ES6的语法,尽管webpack构建时不会报错,但生成的app.js文件末尾部分依旧可以找到这部分ES6语法的代码,这样的代码被用户加载到浏览器中执行,是否能被浏览器支持是无法得到保证的。<br> 为此,我们需要引入Babel,让其把所有浏览器可能不支持的语法转换成ES5的语法。</p> 
  <p>使用Babel的方法也有好多种,官网的帮助文档可以根据环境提供对应的帮助。本文是基于Webpack使用Babel,因此无论是增加的依赖库还是配置流程均只对Webpack的场景有效。我们将使用Webpack关于Babel的一个扩展加载器babel-loader关联这两者。</p> 
  <ul> 
   <li>打开<code>package.json</code> 添加安装依赖</li> 
  </ul> 
  <pre><code>//--package.json
 "devDependencies": {
    ...
    "babel-core": "^6.26.0",
    "babel-loader": "^7.1.2"
  },
</code></pre> 
  <p>上文提到,Babel用于把新版本的JS代码翻译成大多数浏览器都支持的ES5版本的代码。要做到这些翻译,只需要使用对应的扩展即可。例如:</p> 
  <ul> 
   <li>babel-preset-env根据配置环境计算babel对代码填充何种等级的polyfill,已包括es2015的配置,但没有包括stage-x。官方首推。</li> 
   <li>babel-preset-[stage-0、stage-1、stage-2、stage-3]与ES7相关的配置;</li> 
   <li>除此之外,Babel还可以有其他扩展,比如我们希望使用JSX语法,这时需要引入babel-preset-react处理器。</li> 
  </ul> 
  <p>根据官方的推荐,我们暂时先使用这几个:</p> 
  <pre><code> "devDependencies": {
    ...
    "babel-preset-env": "^1.6.1",
    "babel-preset-react": "^6.24.1",
    "babel-preset-stage-0": "^6.24.1",
  },
</code></pre> 
  <p>所以bable的依赖包我们先安装5个。然后执行<code>cnpm install</code></p> 
  <ul> 
   <li>bable的配置属于通用的基本配置,所以我们打开刚才的<code>webpack.base.conf.js</code>,添加rules配置</li> 
  </ul> 
  <pre><code>const HtmlWebpackPlugin = require('html-webpack-plugin'); //第二步导入
module.exports = {
    entry: './src/main', //main.js中的.js可以省略,前面的./不能省
    plugins: [
  	    ...
    ],
    module: {
         rules: [
	      {
	        test: /\.js$/,
	        exclude: /node_modules/,
	        use: {
	          loader: 'babel-loader',
	          options: {
	            presets: ['env', 'stage-0', 'react'],
	            plugins: []
	          }
	        }
	      }
    	]
    }
}
</code></pre> 
  <p>这样我们就使用了bable-loader作为js的解析器。依次使用react、stage-0、env插件进行解析。</p> 
  <ul> 
   <li>修改我们的main.js 这时我们可以使用一些jsx语法试试了:</li> 
  </ul> 
  <pre><code>import React from 'react';
import ReactDOM from 'react-dom';
class Text extends React.Component {
  render() {
    return (
      <p>This is a react Component</p>
    );
  }
}
ReactDOM.render(<Text/>, document.getElementById('main'));
</code></pre> 
  <p>在根目录执行<code>npm run dev</code>查看效果</p> 
  <p><a href="http://img.e-com-net.com/image/info8/4d8fb05a929b40ac8cd5e5ec4969e9dc.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/4d8fb05a929b40ac8cd5e5ec4969e9dc.jpg" alt="从零开始使用webpack(4.x)+bable+react+ant-design配置单页面应用开发环境(附模板)_第4张图片" width="650" height="191" style="border:1px solid black;"></a><br> 没错。这下子我们完成了jsx语法的打包!Babel很好地工作了。</p> 
  <h2>5 使用Ant Design作为React的UI库</h2> 
  <p>就跟iview一样。我们要的各种漂亮的组件不可能由我们自己去一个个实现,这在项目的开发周期限制下是不允许的。于是乎基于React的各种组件UI库相应而生,而我选择<code>Ant Design</code>是因为其与iview风格、api及管网样式几乎一致。可以减少很多学习的时间。<br> 在<code>package.json</code>中添加ant-design依赖,由于是运行时依赖,所以需要加在<code>dependencies</code>中</p> 
  <pre><code>"dependencies": {
    "antd": "^3.13.5",
    "react": "^16.0.0",
    "react-dom": "^16.0.0"
  }
</code></pre> 
  <p>执行<code>cnpm install</code> 安装依赖。</p> 
  <p>好了,现在我们可以直接使用Ant Design的UI了。修改main.js,引入<code>ant-design</code>的<code>DatePicker</code>:</p> 
  <pre><code>import React from 'react';
import ReactDOM from 'react-dom';
import { DatePicker } from 'antd';
class Text extends React.Component {
  render() {
    return (
      <div>
        <p>This is a react Component</p>
        <DatePicker/>
      </div>
    );
  }
}
ReactDOM.render(<Text/>, document.getElementById('main'));
</code></pre> 
  <p>执行<code>npm run dev</code>,在浏览器中可以看到多了个日期选择器,但是没有相应的样式。</p> 
  <h2>6 使用webpack加载样式表</h2> 
  <p>想要在js中引入css样式表,需要添加webpack的加载器,这样在js中引入的css样式将会被webpack构建成以动态方式插入到html文件中。</p> 
  <p>针对css样式,需要下面两个加载器:</p> 
  <ul> 
   <li>style-loader</li> 
   <li>css-loader</li> 
  </ul> 
  <p>我们在<code>package.json</code>中安装如下依赖包</p> 
  <pre><code>  "devDependencies": {
     ...
    "css-loader": "^2.1.0",
    "style-loader": "^0.23.1"
  },
</code></pre> 
  <p>执行<code>cnpm install</code>安装依赖。</p> 
  <p>css-loader的配置属于通用的基本配置,所以我们打开刚才的<code>webpack.base.conf.js</code>,添加css解析器:</p> 
  <pre><code> module: {
        rules: [
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: ['env', 'stage-0', 'react'],
                        plugins: []
                    }
                }
            },
            {
                test: /\.css$/,
                use: ['style-loader', 'css-loader']
            }
        ]
    }
</code></pre> 
  <blockquote> 
   <p>注意:因为antd的样式是放在node_modules中的,不要在css的loader中添加exclude命令刨除掉node_modules目录。</p> 
  </blockquote> 
  <p>然后我们在main.js中引入antd的样式表:</p> 
  <pre><code>//--main.js
...
import { DatePicker } from 'antd';
import 'antd/dist/antd.css';  // Add
...
</code></pre> 
  <p>再次执行热更新服务器查看效果。发现时间选择器已经有样式了。</p> 
  <h2>7 配置按需加载</h2> 
  <p>不知道大家有没有发现现在页面的加载速度明显变慢了。这里是因为上述方法实际上加载整个antd包到最终生成的app.js文件中了。控制台也会看到相应的警告:<br> <img src="http://img.e-com-net.com/image/info8/d3b3bcbc3ad0495fb2498c192887e02b.jpg" alt="在这里插入图片描述" width="650" height="15"><br> 这里很明显,我们需要配置按需加载。配置按需加载需要使用另外一个Babel的插件<code>babel-plugin-import</code>,在<code>package.json</code>中添加引用:</p> 
  <pre><code>"devDependencies": {
	...
    "babel-plugin-import": "^1.11.0"
    ...
  }
</code></pre> 
  <p>执行<code>cnpm install</code>安装依赖。</p> 
  <p>然后修改<code>webpack.base.conf.js</code>中bable加载的方式,使用插件<code>babel-plugin-import</code>:</p> 
  <pre><code>module.exports = {
    module: {
        rules: [
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: ['env', 'stage-0', 'react'],
                        plugins: [['import', { "libraryName": "antd", "style": "css" }]]//--通过bable-plugin-import依赖 实现antd按需加载
                    }
                }
            }
        ]
    }
}
</code></pre> 
  <p>大工告成。打包生成的app.js由13w行缩小到了5w行。注意,配置完按需加载之后,<code>main.js</code>中就不需要在手动引入anti的css样式了,所以我们可以去掉这一行。发现时间选择器能够正常加载样式。</p> 
  <blockquote> 
   <p>import ‘antd/dist/antd.css’;</p> 
  </blockquote> 
  <h1>五 其他配置</h1> 
  <h2>1 使用less语法加载器</h2> 
  <p>less是比较主流的样式语法。我在项目中经常使用,同样的,如果你也想在该项目中使用less语法,那么就需要使用less-loader。</p> 
  <ul> 
   <li>在项目src文件夹下新建一个styles文件夹,专门放置我们项目中用到的各种样式,文件夹下新建一个<code>main.less</code></li> 
  </ul> 
  <pre><code>#main
{
    .my-image{
        width: 400px;
        height: 500px;
    }
}
</code></pre> 
  <ul> 
   <li>在<code>main.js</code>中增加一个类名为<code>my-image</code>的div元素,并且import<code>main.less</code></li> 
  </ul> 
  <pre><code>import React from 'react';
import ReactDOM from 'react-dom';
import { DatePicker } from 'antd';
import './styles/main.less'
// import 'antd/dist/antd.css';  // Add
class Text extends React.Component {

    render() {
        return (
            <div>
            <p>This is a react Component123</p>
            <div className = "my-image" ></div>
            <DatePicker/>
            </div>
        );
    }
}
ReactDOM.render(<Text />, document.getElementById('main'));
</code></pre> 
  <blockquote> 
   <p>注意: react语法中class被替换为了className</p> 
  </blockquote> 
  <p>当然,less是无法被webpack识别的。所以对应的,我们需要为less添加对应的加载器。这里我们就需要<code>less-loader</code>了,当然,less-loader依赖less</p> 
  <ul> 
   <li>在<code>package.json</code>中添加依赖:</li> 
  </ul> 
  <pre><code>//--package.json
  "devDependencies": {
	...
   "less": "^2.7.3",
    "less-loader": "^4.0.5",
    ...
  }
</code></pre> 
  <p>执行<code>cnpm install</code>安装依赖。</p> 
  <ul> 
   <li>在<code>webpack.base.conf.js</code>中添加less后缀文件的加载器:</li> 
  </ul> 
  <pre><code>...
    {
         test: /\.css$/,
         use: ['style-loader', 'css-loader']
     },
     {
         test: /\.less$/,
         use: ['style-loader', 'css-loader', 'less-loader']
     }
 ...
</code></pre> 
  <p>这样配置是因为<code>less-loader</code>依赖<code>css-loader</code>,而<code>css-loader</code>依赖于<code>style-loader</code>;<br> 运行服务器,发现样式表被正常应用到了html文件中。打开<code>F12</code>调试工具,发现所有的样式被编译后转化为了样式表被放在了<code>head</code>标签上:<br> <a href="http://img.e-com-net.com/image/info8/d583db3528764ccdbbb556bcbce1a6eb.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/d583db3528764ccdbbb556bcbce1a6eb.jpg" alt="从零开始使用webpack(4.x)+bable+react+ant-design配置单页面应用开发环境(附模板)_第5张图片" width="650" height="230" style="border:1px solid black;"></a></p> 
  <h2>2 在react中引用图片资源</h2> 
  <p>我们在项目中必不可少的就是引用图片资源。对于图片资源,我们也需要使用对应的loader,来确保webpack对其能够进行正常的处理。为此我们需要引入<code>url-loader</code>对于图片资源进行处理。</p> 
  <ul> 
   <li>安装url-loader</li> 
  </ul> 
  <pre><code>"devDependencies": {
    ...
    "url-loader": "^1.1.2"
  }
</code></pre> 
  <p>然后执行<code>cnmp install</code></p> 
  <ul> 
   <li>在<code>webpack.base.conf.js</code>中添加对应的解析器</li> 
  </ul> 
  <pre><code>...
 {
     test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
     loader: 'url-loader',
     options: {
         limit: 10000,
         name: 'img/[name].[hash:7].[ext]'
     }
 }
 ...
</code></pre> 
  <p>表示对如上后缀资源的都采用url-loader处理。</p> 
  <p><code>limit</code> 属性表示,当资源文件的大小没有超过该值时(单位:字节),编译过后统一转换为base64编码在项目中引用。超过之后,按照<code>name</code>属性配置的目录生成在<code>打包根目录</code>下,以命名规则进行命名。我们这里先设置为10000.</p> 
  <p>这时我们修改原先的main.less,将div设置一个一个背景图片</p> 
  <pre><code>#main
{
    .my-image{
        width: 400px;
        height: 500px;
        background: url("../images/logo.png")
    }
}
</code></pre> 
  <p>打开<code>dev</code>服务器,发现图片能正常显示。打开<code>F12</code>查看图片,发现图片被转为了base64编码:</p> 
  <p><a href="http://img.e-com-net.com/image/info8/f300db5359db4918b0fe525538e7c93e.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/f300db5359db4918b0fe525538e7c93e.jpg" alt="从零开始使用webpack(4.x)+bable+react+ant-design配置单页面应用开发环境(附模板)_第6张图片" width="650" height="135" style="border:1px solid black;"></a><br> 然后我们再修改limit属性,将其设置为很小的数字 8.再次重启服务器,查看对比结果。</p> 
  <p>嗷。居然报错了~</p> 
  <p><a href="http://img.e-com-net.com/image/info8/d18b88c4fe59447fac68017e2eeea6a7.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/d18b88c4fe59447fac68017e2eeea6a7.jpg" alt="在这里插入图片描述" width="650" height="73"></a></p> 
  <p>原因很简单,因为图片大小超过了设定的大小,url-loader需要调用<code>file-loader</code>进行文件复制和拷贝等操作,所以需要安装<code>file-loader</code></p> 
  <pre><code>//--package.json
 "devDependencies": {
    "file-loader": "^3.0.1"
  }
</code></pre> 
  <p>执行<code>cnpm install</code> 安装后重新执行,重启服务器,得到正确的结果:</p> 
  <p><a href="http://img.e-com-net.com/image/info8/529401bd616940d3a3869cb8d98c8dac.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/529401bd616940d3a3869cb8d98c8dac.jpg" alt="从零开始使用webpack(4.x)+bable+react+ant-design配置单页面应用开发环境(附模板)_第7张图片" width="650" height="135" style="border:1px solid black;"></a></p> 
  <p>这时,dist下自动生成了img目录,将原有的图片拷贝了过来,并进行了重命名:</p> 
  <p><a href="http://img.e-com-net.com/image/info8/906fdc97e2b64c978b3b931a502840e2.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/906fdc97e2b64c978b3b931a502840e2.jpg" alt="从零开始使用webpack(4.x)+bable+react+ant-design配置单页面应用开发环境(附模板)_第8张图片" width="650" height="147" style="border:1px solid black;"></a></p> 
  <h2>3 将样式表单独打包发布成css文件</h2> 
  <p>通过上面的例子我们发现,所有的样式都被放到了编译后的html的头部中,如果想将所有的样式统一打包到一个文件中,岂不是很美观。要做到这样,我们需要使用另外一个插件<code>mini-css-extract-plugin</code>.其实在webpack3.x的时候,大家都是采用的<code>extract-text-webpack-plugin</code>进行css的单独处理。但是在4.x,该插件并不支持,并且在4.x官网推荐使用的就是<code>mini-css-extract-plugin</code>,所以我们今天就以该插件为例。</p> 
  <ul> 
   <li>在<code>package.json</code>中安装依赖:</li> 
  </ul> 
  <pre><code> "devDependencies": {
    ...
    "mini-css-extract-plugin":"^0.5.0"
  },
</code></pre> 
  <p>执行<code>cnpm install</code>安装依赖。</p> 
  <ul> 
   <li>打开<code>webpack.base.conf.js</code>,先修改less文件的加载方式,将原先依赖的<code>style-loader</code>替换为<code>MiniCssExtractPlugin.loader</code></li> 
  </ul> 
  <pre><code>//--webpack.base.conf.js

 const MiniCssExtractPlugin = require("mini-css-extract-plugin"); //--注意需要引入
  ...
  module: {
        rules: [
            {
                test: /\.css$/,
                use: ['style-loader', 'css-loader']
            },
            {
                test: /\.less$/,
                use: [MiniCssExtractPlugin.loader, 'css-loader', 'less-loader']
            }
           ...
        ],
    }
</code></pre> 
  <ul> 
   <li>在<code>webpack.base.conf.js</code>的<code>plugins</code>配置选项中声明使用该plugin并且添加其配置</li> 
  </ul> 
  <pre><code>//--webpack.base.conf.js
plugins: [
        new HtmlWebpackPlugin({
           ...
        }),
        new MiniCssExtractPlugin({
            filename: "[name].css",
            chunkFilename: "[id].css"
        })
 ]
</code></pre> 
  <ul> 
   <li>执行npm run dev。</li> 
  </ul> 
  <p><a href="http://img.e-com-net.com/image/info8/16c2d67ce6ea44a09e9935aaf22f7e35.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/16c2d67ce6ea44a09e9935aaf22f7e35.jpg" alt="从零开始使用webpack(4.x)+bable+react+ant-design配置单页面应用开发环境(附模板)_第9张图片" width="650" height="139" style="border:1px solid black;"></a><br> 没错!我们现在将css单独独立到了一个文件中了(暂时不管路径,会在下一节提及),并且查看html,在<code>head</code>部分注入了对main.css的引用,原先在<code>style</code>标签中引用的样式消失了。现在大家应该明白<code>style-loader</code>的作用了吧。由于被替换为了<code>MiniCssExtractPlugin.loader</code>,样式注入的流程被替代了。所以不会在html文件的<code>style</code>标签中注入样式了。</p> 
  <p><a href="http://img.e-com-net.com/image/info8/60274bee6aaf4822b0642a35aed9913a.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/60274bee6aaf4822b0642a35aed9913a.jpg" alt="从零开始使用webpack(4.x)+bable+react+ant-design配置单页面应用开发环境(附模板)_第10张图片" width="650" height="115" style="border:1px solid black;"></a><br> 依葫芦画瓢,我们把anti-design的样式也修改注入方式,全部放到main.css中。</p> 
  <pre><code>//--webpack.base.conf.js

 const MiniCssExtractPlugin = require("mini-css-extract-plugin"); //--注意需要引入
  ...
  module: {
        rules: [
            {
                test: /\.css$/,
                use: [MiniCssExtractPlugin.loader, 'css-loader']
            },
            {
                test: /\.less$/,
                use: [MiniCssExtractPlugin.loader, 'css-loader', 'less-loader']
            }
           ...
        ],
    }
</code></pre> 
  <p>重新运行<code>npm run dev</code>。</p> 
  <p>完美。现在html中已经没有一大坨样式了,仅有对<code>main.css</code>的引用打开<code>main.css</code>,发现原来的样式都被放到了这里。<br> <a href="http://img.e-com-net.com/image/info8/25499cdc9a42466d842ce4960d7d85d5.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/25499cdc9a42466d842ce4960d7d85d5.jpg" alt="从零开始使用webpack(4.x)+bable+react+ant-design配置单页面应用开发环境(附模板)_第11张图片" width="650" height="170" style="border:1px solid black;"></a></p> 
  <h1>六 发布产品&配置产品环境</h1> 
  <p>截止到上面为止,我们讨论的都是使用<code>webpack-dev-server</code>构建服务器,然后在内存中加载对于webpack编译生成的文件,主要用于开发阶段使用的。虽然配置的写法都在<code>webpack.base.conf.js</code>中,但是我们使用的指令<code>npm run dev</code>使用的都是<code>webpack.dev.conf.js</code>中的配置。当我们发布产品的时候,我们就需要一些不同于<code>dev</code>的配置选项了。</p> 
  <ul> 
   <li>打开<code>webpack.prod.conf.js</code> ,按照<code>webpack.dev.conf.js</code>填写如下内容:</li> 
  </ul> 
  <pre><code>const merge = require('webpack-merge');
const baseWebpackConfig = require('./webpack.base.conf')

module.exports = merge(baseWebpackConfig, {

})
</code></pre> 
  <ul> 
   <li>在根目录执行<code>npm run build</code>;</li> 
  </ul> 
  <p>发现我们的项目根目录下多了一个<code>dist</code>文件夹,打开一看,哇塞。居然就是我们刚才所有在<code>dev</code>模式下的生成的文件结构:<br> <a href="http://img.e-com-net.com/image/info8/2d074e9019a843c8b5e46e6e6fa8b914.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/2d074e9019a843c8b5e46e6e6fa8b914.jpg" alt="从零开始使用webpack(4.x)+bable+react+ant-design配置单页面应用开发环境(附模板)_第12张图片" width="400" height="133" style="border:1px solid black;"></a></p> 
  <p>我们双击<code>index.html</code> 完美,浏览器中也能呈现和<code>dev</code>模式下的一模一样的效果。注意,这里的所有资源都是可以被浏览器直接识别的,没有less,没有es6,也没有jsx等等,只有html,css,js。这就是编译发布的意义,这样所有的浏览器都能兼容运行我们的项目了。只需要一个服务器,将内容放上去托管,大家就可以访问我们的网页了。</p> 
  <p>到这里,其实你已经可以开始开发项目了。但是,还是有一些问题存在的,我们上面<code>prod</code>的配置是完全使用<code>base</code>的配置项。毕竟编译发布的配置和dev的配置还是有区别的。在这里,我列举几点问题和解决,其余的定制配置,还是需要大家自己去实现。只需要记得,在<code>webpack.prod.conf.js</code>中配置编译发布环境,在<code>webpack.dev.conf.js</code>中配置开发环境。在<code>webpack.base.conf.js</code>中配置两者共用的环境即可。</p> 
  <h2>1 打包发布时压缩css文件</h2> 
  <p>webpack5可能会内置CSS 压缩器,webpack4需要自己使用压缩器,可以使用 <code>optimize-css-assets-webpack-plugin</code>插件。 设置 <code>optimization.minimizer</code> 覆盖webpack默认提供的即可。</p> 
  <ul> 
   <li>安装<code>optimize-css-assets-webpack-plugin</code></li> 
  </ul> 
  <pre><code>  "devDependencies": {
	...
    "optimize-css-assets-webpack-plugin": "^5.0.1",
	...
  },
</code></pre> 
  <p>执行<code>cnpm install</code></p> 
  <ul> 
   <li>这时我们需要配置<code>webpack.prod.conf.js</code>:</li> 
  </ul> 
  <pre><code>//--webpack.prod.conf.js
const merge = require('webpack-merge');
const baseWebpackConfig = require('./webpack.base.conf')
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
module.exports = merge(baseWebpackConfig, {
    optimization: {
        minimizer: [
            new OptimizeCSSAssetsPlugin({})
        ]
    }
})
</code></pre> 
  <p>这里我们使用我们安装的插件,然后执行<code>npm run build</code>即可。没错,这时我们发现我们的<code>main.css</code>已经是压缩过的状态了~<br> <a href="http://img.e-com-net.com/image/info8/de8201ceee2046c8941c680af3d94410.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/de8201ceee2046c8941c680af3d94410.jpg" alt="在这里插入图片描述" width="650" height="56"></a></p> 
  <h2>2 打包发布时压缩js文件</h2> 
  <p>不知道大家有没有发现。在执行上一步之前,我们调用<code>npm run build</code>的时候,生成的<code>main.js</code>都是默认压缩的。那是因为webpack4.x的新特性、webpack4新的Mode,且默认值是production,所以都是默认调用其内置的<code>UglifyJsPlugin</code>进行压缩的。但是我们上一步复写了其默认配置。没有指定js压缩器,所以没有压缩js代码。这时候我们需要重新指定。</p> 
  <ul> 
   <li>下载安装<code>uglifyjs-webpack-plugin</code></li> 
  </ul> 
  <pre><code> "devDependencies": {
    "uglifyjs-webpack-plugin": "^2.1.1"
  },
</code></pre> 
  <p>执行<code>cnpm install</code>安装依赖</p> 
  <ul> 
   <li>打开<code>webpack.prod.conf.js</code> 修改<code>optimization</code>配置:</li> 
  </ul> 
  <pre><code>const UglifyJsPlugin = require('uglifyjs-webpack-plugin');  //--注意需要引入
...
optimization: {
        minimizer: [
            new OptimizeCSSAssetsPlugin({}),
            new UglifyJsPlugin({})
        ]
} 
...
</code></pre> 
  <p>这时 我们重新执行<code>npm run build</code>。ok js变成压缩过的版本了。这样可以打打减少我们项目打包出来文件的体积,提高网页加载的速度。<br> <a href="http://img.e-com-net.com/image/info8/f12776fb61354ca9bdbd293f8d0cd483.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/f12776fb61354ca9bdbd293f8d0cd483.jpg" alt="在这里插入图片描述" width="650" height="53"></a></p> 
  <h2>3 资源文件夹优化</h2> 
  <p>一般webpack打包出来的主流结构为一个static资源文件夹,然后是一个html文件。这样的结构合理,清晰。static文件夹内包含css,img,font等静态资源文件。这时候我们要修改我们项目的打包路径,使之符合这种审美。<br> <a href="http://img.e-com-net.com/image/info8/2b9e5f2d576f4f03bb37bfc81598d78c.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/2b9e5f2d576f4f03bb37bfc81598d78c.jpg" alt="在这里插入图片描述" width="320" height="70"></a></p> 
  <p>我们先来看看我们现在打包生成的目录结构:<br> <a href="http://img.e-com-net.com/image/info8/c960333e5978432c819ce737651babc0.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/c960333e5978432c819ce737651babc0.jpg" alt="从零开始使用webpack(4.x)+bable+react+ant-design配置单页面应用开发环境(附模板)_第13张图片" width="321" height="147" style="border:1px solid black;"></a><br> 可以看到确实很丑。很乱,只有img文件夹是按照我们的想法的规则的。所以接下来我们要将其结构优化。</p> 
  <ul> 
   <li>首先我们要讲css的生成路径修改一下。改为由<code>css</code>文件夹包裹:<br> 理所当然的,我们想到了我们的<code>MiniCssExtractPlugin</code>,他是我们打包css最后一层调用的插件。于是我们修改他的配置:</li> 
  </ul> 
  <pre><code>//--webpack.base.conf.js
  ...
  new MiniCssExtractPlugin({
        filename: "css/[name].css",
        chunkFilename: "[id].css"
 })
</code></pre> 
  <p>因为官网说,<code>filename</code>的配置方式和<code>chunkFilename</code>的配置方式和<code>webpack</code>完全一致,所以我们尝试修改生成css的路径。<br> 保存之后,执行编译指令<code>npm run build</code>。<br> <a href="http://img.e-com-net.com/image/info8/c09d95e5364643a185f3f816ea3f9c03.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/c09d95e5364643a185f3f816ea3f9c03.jpg" alt="从零开始使用webpack(4.x)+bable+react+ant-design配置单页面应用开发环境(附模板)_第14张图片" width="315" height="135" style="border:1px solid black;"></a><br> 没错,成功了,我们将<code>main.css</code>打包进了<code>css</code>文件夹下。</p> 
  <ul> 
   <li>由于生成目录是公用配置,<code>dev</code>和<code>prod</code>模式均要使用。所以修改<code>webpack.base.config.js</code>中配置<code>output</code> 优化js的生成目录,并且换个名叫app.js:</li> 
  </ul> 
  <pre><code>//--webpack.base.config.js
module.exports = merge(baseWebpackConfig, {
    output: {
        filename: 'js/app[hash].js', // dist文件夹不存在时,会自动创建
        hashDigestLength: 8 // 默认长度是20
    }
})
</code></pre> 
  <p>记得删除<code>webpack.dev.config.js</code>中<code>output</code>的配置,这样<code>dev</code>模式才能继承到。<br> 我们先运行<code>npm run build</code>编译。<br> <a href="http://img.e-com-net.com/image/info8/3a52428435c94200ba1c7c1324ce09d8.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/3a52428435c94200ba1c7c1324ce09d8.jpg" alt="从零开始使用webpack(4.x)+bable+react+ant-design配置单页面应用开发环境(附模板)_第15张图片" width="345" height="176" style="border:1px solid black;"></a><br> 没错!现在js也被我们套了一层了。</p> 
  <ul> 
   <li>将所有的资源包裹进<code>static</code>文件夹</li> 
  </ul> 
  <p>这里我们需要了解一个<code>webpack</code>的2个属性<code>output.publicPath</code>和<code>output.path</code>。<code>output.path</code>该属性表示将所有资源打包进根目录下的对应路径内。而<code>output.publicPath</code>表示html在引用这些资源的时候,默认在前面添加的路径。</p> 
  <p><strong>第一步</strong></p> 
  <p>修改一下<code>output.publicPath</code>,由于这是基本配置,所以我们打开<code>webpack.base.config.js</code>,添加如下语句</p> 
  <pre><code>module.exports = {
     ...
    output: {
        filename: './js/app[hash].js', // dist文件夹不存在时,会自动创建
        hashDigestLength: 8,// 默认长度是20
        publicPath:"./static/"
    }
    ...
 }
</code></pre> 
  <p>执行一次<code>npm run build</code> 然后观察生成的html文件。<br> <a href="http://img.e-com-net.com/image/info8/d83d415f001743ef82e2a308a6935f97.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/d83d415f001743ef82e2a308a6935f97.jpg" alt="从零开始使用webpack(4.x)+bable+react+ant-design配置单页面应用开发环境(附模板)_第16张图片" width="650" height="130" style="border:1px solid black;"></a><br> 大家应该猜到了?就是这个意思,引用资源的前缀都会添加这个。我们的目的达到了。接下来就是把资源放到<code>static</code>文件夹下。</p> 
  <p><strong>第二步</strong><br> 还是上述文件<code>webpack.base.config.js</code> 我们再添加<code>path</code>的配置</p> 
  <pre><code>var path = require('path');//--path是node包中的类。注意引用
module.exports = {
     ...
    output: {
        filename: './js/app[hash].js', // dist文件夹不存在时,会自动创建
        hashDigestLength: 8,// 默认长度是20
        publicPath:"./static/",
        path:path.resolve(__dirname, '../dist/static')
    }
    ...
 }
</code></pre> 
  <p>表示资源生成的路径为取相对路径的dist再拼上static。我们再编译一次。`npm run build</p> 
  <p><a href="http://img.e-com-net.com/image/info8/36ac95b5fc25462995576bb20660f3ef.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/36ac95b5fc25462995576bb20660f3ef.jpg" alt="从零开始使用webpack(4.x)+bable+react+ant-design配置单页面应用开发环境(附模板)_第17张图片" width="362" height="144" style="border:1px solid black;"></a>`</p> 
  <p>ok。完美。现在只剩下最后一步,将<code>index.html</code>移到<code>static</code>外,与其同级。</p> 
  <p><strong>第三步</strong></p> 
  <p>还是上述文件<code>webpack.base.config.js</code> 我们修改<code>HtmlWebpackPlugin</code>的配置。将<code>filename</code>属性修改为当前目录上一层:</p> 
  <pre><code>...
plugins: [
        new HtmlWebpackPlugin(
            {
                title: 'SEIE5.0', // html5文件中<title>部分
                filename: '../index.html', 
                template: './src/template/template.html',
                inject: "body"
            }
        )
        ...
    ]
    ...
</code></pre> 
  <p><a href="http://img.e-com-net.com/image/info8/d4b0927f9bd648d08e8a47f31da7ffa2.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/d4b0927f9bd648d08e8a47f31da7ffa2.jpg" alt="从零开始使用webpack(4.x)+bable+react+ant-design配置单页面应用开发环境(附模板)_第18张图片" width="346" height="146" style="border:1px solid black;"></a><br> 哈哈。大功告成。兴奋之余点击index.html查看效果,得意之余,突然发现引用的图片没了。没了。于是赶紧看控制台,果然。图片路径并不能正确找到。<br> <a href="http://img.e-com-net.com/image/info8/20132a49c73b451a877dd5fd11bdfa5d.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/20132a49c73b451a877dd5fd11bdfa5d.jpg" alt="从零开始使用webpack(4.x)+bable+react+ant-design配置单页面应用开发环境(附模板)_第19张图片" width="650" height="137" style="border:1px solid black;"></a><br> 那一行小字是引用路径,截图的原因看不太清楚:</p> 
  <p><code>file:///E:/github/webpack_test/dist/static/css/static/img/logo.3a54fdd.png</code></p> 
  <p>明显路径不对。本能的,由于请求是在css文件中发出的,所以我们去看打包生成的css文件。虽然被压缩过了,最后一行还是能找到:<br> <a href="http://img.e-com-net.com/image/info8/14e4f249c9964865949841094711b259.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/14e4f249c9964865949841094711b259.jpg" alt="在这里插入图片描述" width="650" height="51"></a><br> 原来是css-loader的问题。由于是相对路径,所以这个url大家都知道,会再css文件夹下查找图片。这当然是找不到的,应该在上一层。所以肯定是<code>url-loader</code>的问题啦。于是我们打开<code>url-loader</code>的配置项,添加<code>publicPath</code>选项,让所有的图片引用都向上一层寻找,这跟webpack的<code>publicPath</code>表示的是同一个意义:</p> 
  <p>打开<code>webpack.base.config.js</code></p> 
  <pre><code>...
module: {
        rules: [
           ...
            {
                test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
                loader: 'url-loader',
                options: {
                    limit: 8,
                    name: 'img/[name].[hash:7].[ext]',
                    publicPath:"../"
                }
            },
        ],
    },
    ...
</code></pre> 
  <p>执行<code>npm run build</code>,再次打开浏览器查看最新的html。这次图片的路径就对了。</p> 
  <p><a href="http://img.e-com-net.com/image/info8/15bf079623d1435a8aac379b860de3af.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/15bf079623d1435a8aac379b860de3af.jpg" alt="从零开始使用webpack(4.x)+bable+react+ant-design配置单页面应用开发环境(附模板)_第20张图片" width="650" height="129" style="border:1px solid black;"></a></p> 
  <p>最后我们来验证下dev是否正常 <code>npm run dev</code> 服务器开启成功,页面加载成功,内存中生成的文件结构也是我们预先设定的结构:</p> 
  <p><a href="http://img.e-com-net.com/image/info8/36c8b09000ac443da6327b7d450042f1.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/36c8b09000ac443da6327b7d450042f1.jpg" alt="从零开始使用webpack(4.x)+bable+react+ant-design配置单页面应用开发环境(附模板)_第21张图片" width="650" height="112" style="border:1px solid black;"></a></p> 
  <h2>4 关于调试代码(source-map)</h2> 
  <p>执行<code>npm run dev</code>。假如我们现在需要调试代码怎么办?app.js已经被打包的密密麻麻的,根本没办法打断点。这个时候我们就需要配置<code>devtool</code>了。关于<code>devtool</code>的详细配置和各参数的区别,可以参考这篇文章。</p> 
  <pre><code>//-webpack.base.conf.js
module.exports = merge(baseWebpackConfig, {
   ...
    devtool: '#source-map',
   ...
})
</code></pre> 
  <p><code>#source-map</code>表示对应的js生成对应的map映射文件,方便调试。这里还有一个坑我已经帮你们趟了。当我们使用<code>UglifyJsPlugin</code>时,如果要使用<code>source-map</code>,必须要指定<code>sourceMap</code>为true;这是因为在webpack的官方文档中有下面一句话:</p> 
  <blockquote> 
   <p>When using the uglifyjs-webpack-plugin you must provide the sourceMap: true option to enable SourceMap support.</p> 
  </blockquote> 
  <p>也就是当使用了uglifyjs-webpack-plugin 插件时,sourceMap这个值的默认值是false,不开启map。如果要启用map,需要在插件中配置sourceMap值为true。</p> 
  <pre><code>//--webpack.prod.config.js
const merge = require('webpack-merge');
const baseWebpackConfig = require('./webpack.base.conf')
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
module.exports = merge(baseWebpackConfig, {
    devtool: '#source-map',
    optimization: {
        minimizer: [
            new OptimizeCSSAssetsPlugin({}),
            new UglifyJsPlugin({sourceMap: true})
        ]
    } 
})
</code></pre> 
  <p>我们运行<code>npm run build</code>查看效果:</p> 
  <p><a href="http://img.e-com-net.com/image/info8/6206f1315f61410eba172cd30b8302b1.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/6206f1315f61410eba172cd30b8302b1.jpg" alt="从零开始使用webpack(4.x)+bable+react+ant-design配置单页面应用开发环境(附模板)_第22张图片" width="290" height="176" style="border:1px solid black;"></a></p> 
  <p>在js中生成了对应的map文件。</p> 
  <p>我们再执行<code>npm run dev</code> 打开f12 这时候按下Ctrl + P,发现我们可以打开源码中的<code>main.js</code>,加上一个断点,刷新页面:</p> 
  <p><a href="http://img.e-com-net.com/image/info8/f2b71e5d1c58445693c198737441b813.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/f2b71e5d1c58445693c198737441b813.jpg" alt="从零开始使用webpack(4.x)+bable+react+ant-design配置单页面应用开发环境(附模板)_第23张图片" width="650" height="159" style="border:1px solid black;"></a><br> ok。现在可以进行调试了。</p> 
  <p>其实<code>dev</code>模式和<code>prod</code>模式应该采用不同的source-map以提高效率。这里我没有深入研究,希望懂的博友们可以留言给予帮助。</p> 
  <h1>七 结语</h1> 
  <p>终于写完了。这篇文章写的很长时间,也是项目一边搭建,一边写的。期间遇到了不少问题,查过很多解决方案。不过一句古话。磨刀不误砍柴工,作为一个通用的模板项目,多付出些心血也是值得的。况且在写这篇博客的同时,也温习并且回顾了webpack很多的知识点。虽然这篇博客涉及的只是一小部分基础的功能,但是应对一般的项目已经绰绰有余了。</p> 
  <p>还有,如果大家在搭建项目的过程中发现什么问题或者疑问,欢迎留言评论,同时也欢迎大牛们的批评指正~</p> 
  <p>github项目地址 https://github.com/worlddai/webpack_react.git</p> 
 </div> 
</div>
                            </div>
                        </div>
                    </div>
                    <!--PC和WAP自适应版-->
                    <div id="SOHUCS" sid="1291655194135830528"></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">你可能感兴趣的:(react,webpack)</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/1950060071656419328.htm"
                           title="webpack 浅谈系列之 Loader" target="_blank">webpack 浅谈系列之 Loader</a>
                        <span class="text-muted">KimYYX</span>

                        <div>webpack拥有六大核心部分:Entry、Output、Loaders、Plugins、Mode、BrowserCompatibility,这里就我的理解来稍微聊聊Loaders这个部分。1.认识Loader先放出我对loader的理解:Loader是用来逐个处理指定类型的文件。emmm...下面我们对上面那句话稍微解释下。首先我们要先明确,一个Loader是如何在webpack中配置的,见下面</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/1950039673418084352.htm"
                           title="解决 Webpack 报错 “No module factory available for dependency type: CssDependency“ 的方法" target="_blank">解决 Webpack 报错 “No module factory available for dependency type: CssDependency“ 的方法</a>
                        <span class="text-muted">cmmav33990</span>
<a class="tag" taget="_blank" href="/search/webpack/1.htm">webpack</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>
                        <div>这个错误表明Webpack在处理CSS依赖时找不到合适的模块工厂,通常发生在配置不完整或依赖冲突的情况下。以下是详细的解决方案:核心解决方案方案1:安装并配置正确的CSS处理器(最推荐)bashnpminstall--save-devcss-loaderstyle-loader#或使用mini-css-extract-plugin替代style-loadernpminstall--save-dev</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/1949932110080962560.htm"
                           title="webpack 配置 style-loader时出现错误:Module build failed (from ../node_modules/style-loader/dist/cjs.js)" target="_blank">webpack 配置 style-loader时出现错误:Module build failed (from ../node_modules/style-loader/dist/cjs.js)</a>
                        <span class="text-muted">.ToString()°</span>
<a class="tag" taget="_blank" href="/search/webpack/1.htm">webpack</a><a class="tag" taget="_blank" href="/search/javascript/1.htm">javascript</a><a class="tag" taget="_blank" href="/search/es6%2Fes7/1.htm">es6/es7</a><a class="tag" taget="_blank" href="/search/webpack/1.htm">webpack</a><a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a><a class="tag" taget="_blank" href="/search/node.js/1.htm">node.js</a>
                        <div>webpack配置style-loader时出现错误,Modulebuildfailed(from…/node_modules/style-loader/dist/cjs.js):TypeError:this.getOptionsisnotafunctionatObject.loader1.确保loader配置中的顺序,loader的执行顺序是从右到左,从下到上的,这里要注意style-loade</div>
                    </li>
                    <li><a href="/article/1949892598973919232.htm"
                           title="webpack实用教程" target="_blank">webpack实用教程</a>
                        <span class="text-muted">前端的爬行之旅</span>

                        <div>packjson.js终端输入$npminit-y{"name":"2","version":"1.0.0","description":"","main":"webpack.config.js","scripts":{"test":"echo\"Error:notestspecified\"&&exit1",},"keywords":[],"author":"","license":"ISC",</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/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/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/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/1949090081813884928.htm"
                           title="React Native 双向无限滚动组件教程" target="_blank">React Native 双向无限滚动组件教程</a>
                        <span class="text-muted"></span>

                        <div>ReactNative双向无限滚动组件教程项目介绍react-native-bidirectional-infinite-scroll是一个基于ReactNative的FlatList组件扩展库,旨在实现双向无限滚动功能,并保持平滑的滚动体验。该组件允许用户在列表的顶部和底部进行无限滚动加载,适用于需要大量数据展示的应用场景。项目快速启动安装首先,通过npm或yarn安装react-native-</div>
                    </li>
                                <li><a href="/article/112.htm"
                                       title="HQL之投影查询" target="_blank">HQL之投影查询</a>
                                    <span class="text-muted">归来朝歌</span>
<a class="tag" taget="_blank" href="/search/HQL/1.htm">HQL</a><a class="tag" taget="_blank" href="/search/Hibernate/1.htm">Hibernate</a><a class="tag" taget="_blank" href="/search/%E6%9F%A5%E8%AF%A2%E8%AF%AD%E5%8F%A5/1.htm">查询语句</a><a class="tag" taget="_blank" href="/search/%E6%8A%95%E5%BD%B1%E6%9F%A5%E8%AF%A2/1.htm">投影查询</a>
                                    <div>        在HQL查询中,常常面临这样一个场景,对于多表查询,是要将一个表的对象查出来还是要只需要每个表中的几个字段,最后放在一起显示? 
针对上面的场景,如果需要将一个对象查出来: 
HQL语句写“from 对象”即可 
Session session = HibernateUtil.openSession();
		</div>
                                </li>
                                <li><a href="/article/239.htm"
                                       title="Spring整合redis" target="_blank">Spring整合redis</a>
                                    <span class="text-muted">bylijinnan</span>
<a class="tag" taget="_blank" href="/search/redis/1.htm">redis</a>
                                    <div>pom.xml 
 

<dependencies>
		<!-- Spring Data - Redis Library -->
		<dependency>
			<groupId>org.springframework.data</groupId>
			<artifactId>spring-data-redi</div>
                                </li>
                                <li><a href="/article/366.htm"
                                       title="org.hibernate.NonUniqueResultException: query did not return a unique result: 2" target="_blank">org.hibernate.NonUniqueResultException: query did not return a unique result: 2</a>
                                    <span class="text-muted">0624chenhong</span>
<a class="tag" taget="_blank" href="/search/Hibernate/1.htm">Hibernate</a>
                                    <div>参考:http://blog.csdn.net/qingfeilee/article/details/7052736 
org.hibernate.NonUniqueResultException: query did not return a unique result: 2 
        在项目中出现了org.hiber</div>
                                </li>
                                <li><a href="/article/493.htm"
                                       title="android动画效果" target="_blank">android动画效果</a>
                                    <span class="text-muted">不懂事的小屁孩</span>
<a class="tag" taget="_blank" href="/search/android%E5%8A%A8%E7%94%BB/1.htm">android动画</a>
                                    <div>前几天弄alertdialog和popupwindow的时候,用到了android的动画效果,今天专门研究了一下关于android的动画效果,列出来,方便以后使用。 
 
Android 平台提供了两类动画。 一类是Tween动画,就是对场景里的对象不断的进行图像变化来产生动画效果(旋转、平移、放缩和渐变)。 
第二类就是 Frame动画,即顺序的播放事先做好的图像,与gif图片原理类似。 
 
</div>
                                </li>
                                <li><a href="/article/620.htm"
                                       title="js delete 删除机理以及它的内存泄露问题的解决方案" target="_blank">js delete 删除机理以及它的内存泄露问题的解决方案</a>
                                    <span class="text-muted">换个号韩国红果果</span>
<a class="tag" taget="_blank" href="/search/JavaScript/1.htm">JavaScript</a>
                                    <div>delete删除属性时只是解除了属性与对象的绑定,故当属性值为一个对象时,删除时会造成内存泄露  (其实还未删除) 
举例: 

var person={name:{firstname:'bob'}}
var p=person.name
delete person.name
p.firstname  -->'bob'
// 依然可以访问p.firstname,存在内存泄露</div>
                                </li>
                                <li><a href="/article/747.htm"
                                       title="Oracle将零干预分析加入网络即服务计划" target="_blank">Oracle将零干预分析加入网络即服务计划</a>
                                    <span class="text-muted">蓝儿唯美</span>
<a class="tag" taget="_blank" href="/search/oracle/1.htm">oracle</a>
                                    <div>由Oracle通信技术部门主导的演示项目并没有在本月较早前法国南斯举行的行业集团TM论坛大会中获得嘉奖。但是,Oracle通信官员解雇致力于打造一个支持零干预分配和编制功能的网络即服务(NaaS)平台,帮助企业以更灵活和更适合云的方式实现通信服务提供商(CSP)的连接产品。这个Oracle主导的项目属于TM Forum Live!活动上展示的Catalyst计划的19个项目之一。Catalyst计</div>
                                </li>
                                <li><a href="/article/874.htm"
                                       title="spring学习——springmvc(二)" target="_blank">spring学习——springmvc(二)</a>
                                    <span class="text-muted">a-john</span>
<a class="tag" taget="_blank" href="/search/springMVC/1.htm">springMVC</a>
                                    <div>Spring MVC提供了非常方便的文件上传功能。 
1,配置Spring支持文件上传: 
DispatcherServlet本身并不知道如何处理multipart的表单数据,需要一个multipart解析器把POST请求的multipart数据中抽取出来,这样DispatcherServlet就能将其传递给我们的控制器了。为了在Spring中注册multipart解析器,需要声明一个实现了Mul</div>
                                </li>
                                <li><a href="/article/1001.htm"
                                       title="POJ-2828-Buy Tickets" target="_blank">POJ-2828-Buy Tickets</a>
                                    <span class="text-muted">aijuans</span>
<a class="tag" taget="_blank" href="/search/ACM_POJ/1.htm">ACM_POJ</a>
                                    <div>POJ-2828-Buy Tickets 
http://poj.org/problem?id=2828 
线段树,逆序插入 
 
#include<iostream>#include<cstdio>#include<cstring>#include<cstdlib>using namespace std;#define N 200010struct</div>
                                </li>
                                <li><a href="/article/1128.htm"
                                       title="Java Ant build.xml详解" target="_blank">Java Ant build.xml详解</a>
                                    <span class="text-muted">asia007</span>
<a class="tag" taget="_blank" href="/search/build.xml/1.htm">build.xml</a>
                                    <div>1,什么是antant是构建工具2,什么是构建概念到处可查到,形象来说,你要把代码从某个地方拿来,编译,再拷贝到某个地方去等等操作,当然不仅与此,但是主要用来干这个3,ant的好处跨平台   --因为ant是使用java实现的,所以它跨平台使用简单--与ant的兄弟make比起来语法清晰--同样是和make相比功能强大--ant能做的事情很多,可能你用了很久,你仍然不知道它能有</div>
                                </li>
                                <li><a href="/article/1255.htm"
                                       title="android按钮监听器的四种技术" target="_blank">android按钮监听器的四种技术</a>
                                    <span class="text-muted">百合不是茶</span>
<a class="tag" taget="_blank" href="/search/android/1.htm">android</a><a class="tag" taget="_blank" href="/search/xml%E9%85%8D%E7%BD%AE/1.htm">xml配置</a><a class="tag" taget="_blank" href="/search/%E7%9B%91%E5%90%AC%E5%99%A8/1.htm">监听器</a><a class="tag" taget="_blank" href="/search/%E5%AE%9E%E7%8E%B0%E6%8E%A5%E5%8F%A3/1.htm">实现接口</a>
                                    <div>android开发中经常会用到各种各样的监听器,android监听器的写法与java又有不同的地方;  
  
1,activity中使用内部类实现接口 ,创建内部类实例  使用add方法  与java类似 
  
创建监听器的实例 
myLis lis = new myLis(); 
  
使用add方法给按钮添加监听器 
 </div>
                                </li>
                                <li><a href="/article/1382.htm"
                                       title="软件架构师不等同于资深程序员" target="_blank">软件架构师不等同于资深程序员</a>
                                    <span class="text-muted">bijian1013</span>
<a class="tag" taget="_blank" href="/search/%E7%A8%8B%E5%BA%8F%E5%91%98/1.htm">程序员</a><a class="tag" taget="_blank" href="/search/%E6%9E%B6%E6%9E%84%E5%B8%88/1.htm">架构师</a><a class="tag" taget="_blank" href="/search/%E6%9E%B6%E6%9E%84%E8%AE%BE%E8%AE%A1/1.htm">架构设计</a>
                                    <div>        本文的作者Armel Nene是ETAPIX Global公司的首席架构师,他居住在伦敦,他参与过的开源项目包括 Apache Lucene,,Apache Nutch, Liferay 和 Pentaho等。 
        如今很多的公司</div>
                                </li>
                                <li><a href="/article/1509.htm"
                                       title="TeamForge Wiki Syntax & CollabNet User Information Center" target="_blank">TeamForge Wiki Syntax & CollabNet User Information Center</a>
                                    <span class="text-muted">sunjing</span>
<a class="tag" taget="_blank" href="/search/TeamForge/1.htm">TeamForge</a><a class="tag" taget="_blank" href="/search/How+do/1.htm">How do</a><a class="tag" taget="_blank" href="/search/Attachement/1.htm">Attachement</a><a class="tag" taget="_blank" href="/search/Anchor/1.htm">Anchor</a><a class="tag" taget="_blank" href="/search/Wiki+Syntax/1.htm">Wiki Syntax</a>
                                    <div>the CollabNet user information center http://help.collab.net/ 
  
How do I create a new Wiki page? 
A CollabNet TeamForge project can have any number of Wiki pages. All Wiki pages are linked, and</div>
                                </li>
                                <li><a href="/article/1636.htm"
                                       title="【Redis四】Redis数据类型" target="_blank">【Redis四】Redis数据类型</a>
                                    <span class="text-muted">bit1129</span>
<a class="tag" taget="_blank" href="/search/redis/1.htm">redis</a>
                                    <div>概述 
Redis是一个高性能的数据结构服务器,称之为数据结构服务器的原因是,它提供了丰富的数据类型以满足不同的应用场景,本文对Redis的数据类型以及对这些类型可能的操作进行总结。 
Redis常用的数据类型包括string、set、list、hash以及sorted set.Redis本身是K/V系统,这里的数据类型指的是value的类型,而不是key的类型,key的类型只有一种即string</div>
                                </li>
                                <li><a href="/article/1763.htm"
                                       title="SSH2整合-附源码" target="_blank">SSH2整合-附源码</a>
                                    <span class="text-muted">白糖_</span>
<a class="tag" taget="_blank" href="/search/eclipse/1.htm">eclipse</a><a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a><a class="tag" taget="_blank" href="/search/tomcat/1.htm">tomcat</a><a class="tag" taget="_blank" href="/search/Hibernate/1.htm">Hibernate</a><a class="tag" taget="_blank" href="/search/Google/1.htm">Google</a>
                                    <div>今天用eclipse终于整合出了struts2+hibernate+spring框架。 
我创建的是tomcat项目,需要有tomcat插件。导入项目以后,鼠标右键选择属性,然后再找到“tomcat”项,勾选一下“Is a tomcat project”即可。具体方法见源码里的jsp图片,sql也在源码里。 
  
  
补充1:项目中部分jar包不是最新版的,可能导</div>
                                </li>
                                <li><a href="/article/1890.htm"
                                       title="[转]开源项目代码的学习方法" target="_blank">[转]开源项目代码的学习方法</a>
                                    <span class="text-muted">braveCS</span>
<a class="tag" taget="_blank" href="/search/%E5%AD%A6%E4%B9%A0%E6%96%B9%E6%B3%95/1.htm">学习方法</a>
                                    <div>转自: 
http://blog.sina.com.cn/s/blog_693458530100lk5m.html 
http://www.cnblogs.com/west-link/archive/2011/06/07/2074466.html 
  
1)阅读features。以此来搞清楚该项目有哪些特性2)思考。想想如果自己来做有这些features的项目该如何构架3)下载并安装d</div>
                                </li>
                                <li><a href="/article/2017.htm"
                                       title="编程之美-子数组的最大和(二维)" target="_blank">编程之美-子数组的最大和(二维)</a>
                                    <span class="text-muted">bylijinnan</span>
<a class="tag" taget="_blank" href="/search/%E7%BC%96%E7%A8%8B%E4%B9%8B%E7%BE%8E/1.htm">编程之美</a>
                                    <div>package beautyOfCoding;

import java.util.Arrays;
import java.util.Random;

public class MaxSubArraySum2 {

	/**
	 * 编程之美 子数组之和的最大值(二维)
	 */
	private static final int ROW = 5;
	private stat</div>
                                </li>
                                <li><a href="/article/2144.htm"
                                       title="读书笔记-3" target="_blank">读书笔记-3</a>
                                    <span class="text-muted">chengxuyuancsdn</span>
<a class="tag" taget="_blank" href="/search/jquery%E7%AC%94%E8%AE%B0/1.htm">jquery笔记</a><a class="tag" taget="_blank" href="/search/resultMap%E9%85%8D%E7%BD%AE/1.htm">resultMap配置</a><a class="tag" taget="_blank" href="/search/ibatis%E4%B8%80%E5%AF%B9%E5%A4%9A%E9%85%8D%E7%BD%AE/1.htm">ibatis一对多配置</a>
                                    <div>1、resultMap配置 
2、ibatis一对多配置 
3、jquery笔记 
 
1、resultMap配置
当<select resultMap="topic_data">
<resultMap id="topic_data">必须一一对应。
(1)<resultMap class="tblTopic&q</div>
                                </li>
                                <li><a href="/article/2271.htm"
                                       title="[物理与天文]物理学新进展" target="_blank">[物理与天文]物理学新进展</a>
                                    <span class="text-muted">comsci</span>

                                    <div> 
 
      如果我们必须获得某种地球上没有的矿石,才能够进行某些能量输出装置的设计和建造,而要获得这种矿石,又必须首先进行深空探测,而要进行深空探测,又必须获得这种能量输出装置,这个矛盾的循环,会导致地球联盟在与宇宙文明建立关系的时候,陷入困境 
 
      怎么办呢? 
 
 </div>
                                </li>
                                <li><a href="/article/2398.htm"
                                       title="Oracle 11g新特性:Automatic Diagnostic Repository" target="_blank">Oracle 11g新特性:Automatic Diagnostic Repository</a>
                                    <span class="text-muted">daizj</span>
<a class="tag" taget="_blank" href="/search/oracle/1.htm">oracle</a><a class="tag" taget="_blank" href="/search/ADR/1.htm">ADR</a>
                                    <div>Oracle Database 11g的FDI(Fault Diagnosability Infrastructure)是自动化诊断方面的又一增强。 
FDI的一个关键组件是自动诊断库(Automatic Diagnostic Repository-ADR)。 
 
在oracle 11g中,alert文件的信息是以xml的文件格式存在的,另外提供了普通文本格式的alert文件。 
这两份log文</div>
                                </li>
                                <li><a href="/article/2525.htm"
                                       title="简单排序:选择排序" target="_blank">简单排序:选择排序</a>
                                    <span class="text-muted">dieslrae</span>
<a class="tag" taget="_blank" href="/search/%E9%80%89%E6%8B%A9%E6%8E%92%E5%BA%8F/1.htm">选择排序</a>
                                    <div>
    public void selectSort(int[] array){
        int select;
        
        for(int i=0;i<array.length;i++){
            select = i;
            
            for(int k=i+1;k<array.leng</div>
                                </li>
                                <li><a href="/article/2652.htm"
                                       title="C语言学习六指针的经典程序,互换两个数字" target="_blank">C语言学习六指针的经典程序,互换两个数字</a>
                                    <span class="text-muted">dcj3sjt126com</span>
<a class="tag" taget="_blank" href="/search/c/1.htm">c</a>
                                    <div>示例程序,swap_1和swap_2都是错误的,推理从1开始推到2,2没完成,推到3就完成了 
# include <stdio.h>

void swap_1(int, int);
void swap_2(int *, int *);
void swap_3(int *, int *);

int main(void)
{
	int a = 3;
	int b = </div>
                                </li>
                                <li><a href="/article/2779.htm"
                                       title="php 5.4中php-fpm 的重启、终止操作命令" target="_blank">php 5.4中php-fpm 的重启、终止操作命令</a>
                                    <span class="text-muted">dcj3sjt126com</span>
<a class="tag" taget="_blank" href="/search/PHP/1.htm">PHP</a>
                                    <div>php 5.4中php-fpm 的重启、终止操作命令: 
查看php运行目录命令:which php/usr/bin/php 
查看php-fpm进程数:ps aux | grep -c php-fpm 
查看运行内存/usr/bin/php  -i|grep mem 
重启php-fpm/etc/init.d/php-fpm restart 
在phpinfo()输出内容可以看到php</div>
                                </li>
                                <li><a href="/article/2906.htm"
                                       title="线程同步工具类" target="_blank">线程同步工具类</a>
                                    <span class="text-muted">shuizhaosi888</span>
<a class="tag" taget="_blank" href="/search/%E5%90%8C%E6%AD%A5%E5%B7%A5%E5%85%B7%E7%B1%BB/1.htm">同步工具类</a>
                                    <div>同步工具类包括信号量(Semaphore)、栅栏(barrier)、闭锁(CountDownLatch) 
  
闭锁(CountDownLatch) 
public class RunMain {
	public long timeTasks(int nThreads, final Runnable task) throws InterruptedException {
		fin</div>
                                </li>
                                <li><a href="/article/3033.htm"
                                       title="bleeding edge是什么意思" target="_blank">bleeding edge是什么意思</a>
                                    <span class="text-muted">haojinghua</span>
<a class="tag" taget="_blank" href="/search/DI/1.htm">DI</a>
                                    <div>不止一次,看到很多讲技术的文章里面出现过这个词语。今天终于弄懂了——通过朋友给的浏览软件,上了wiki。  
我再一次感到,没有辞典能像WiKi一样,给出这样体贴人心、一清二楚的解释了。为了表达我对WiKi的喜爱,只好在此一一中英对照,给大家上次课。 
  
In computer science, bleeding edge is a term that </div>
                                </li>
                                <li><a href="/article/3160.htm"
                                       title="c中实现utf8和gbk的互转" target="_blank">c中实现utf8和gbk的互转</a>
                                    <span class="text-muted">jimmee</span>
<a class="tag" taget="_blank" href="/search/c/1.htm">c</a><a class="tag" taget="_blank" href="/search/iconv/1.htm">iconv</a><a class="tag" taget="_blank" href="/search/utf8%26gbk%E7%BC%96%E7%A0%81/1.htm">utf8&gbk编码</a>
                                    <div>#include <iconv.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <sys/stat.h>

int code_c</div>
                                </li>
                                <li><a href="/article/3287.htm"
                                       title="大型分布式网站架构设计与实践" target="_blank">大型分布式网站架构设计与实践</a>
                                    <span class="text-muted">lilin530</span>
<a class="tag" taget="_blank" href="/search/%E5%BA%94%E7%94%A8%E6%9C%8D%E5%8A%A1%E5%99%A8/1.htm">应用服务器</a><a class="tag" taget="_blank" href="/search/%E6%90%9C%E7%B4%A2%E5%BC%95%E6%93%8E/1.htm">搜索引擎</a>
                                    <div>1.大型网站软件系统的特点? 
a.高并发,大流量。 
b.高可用。 
c.海量数据。 
d.用户分布广泛,网络情况复杂。 
e.安全环境恶劣。 
f.需求快速变更,发布频繁。 
g.渐进式发展。 
 
2.大型网站架构演化发展历程? 
a.初始阶段的网站架构。 
应用程序,数据库,文件等所有的资源都在一台服务器上。 
b.应用服务器和数据服务器分离。 
c.使用缓存改善网站性能。 
d.使用应用</div>
                                </li>
                                <li><a href="/article/3414.htm"
                                       title="在代码中获取Android theme中的attr属性值" target="_blank">在代码中获取Android theme中的attr属性值</a>
                                    <span class="text-muted">OliveExcel</span>
<a class="tag" taget="_blank" href="/search/android/1.htm">android</a><a class="tag" taget="_blank" href="/search/theme/1.htm">theme</a>
                                    <div>Android的Theme是由各种attr组合而成, 每个attr对应了这个属性的一个引用, 这个引用又可以是各种东西. 
  
在某些情况下, 我们需要获取非自定义的主题下某个属性的内容 (比如拿到系统默认的配色colorAccent), 操作方式举例一则: 
int defaultColor = 0xFF000000;
int[] attrsArray = { andorid.r.</div>
                                </li>
                                <li><a href="/article/3541.htm"
                                       title="基于Zookeeper的分布式共享锁" target="_blank">基于Zookeeper的分布式共享锁</a>
                                    <span class="text-muted">roadrunners</span>
<a class="tag" taget="_blank" href="/search/zookeeper/1.htm">zookeeper</a><a class="tag" taget="_blank" href="/search/%E5%88%86%E5%B8%83%E5%BC%8F/1.htm">分布式</a><a class="tag" taget="_blank" href="/search/%E5%85%B1%E4%BA%AB%E9%94%81/1.htm">共享锁</a>
                                    <div>首先,说说我们的场景,订单服务是做成集群的,当两个以上结点同时收到一个相同订单的创建指令,这时并发就产生了,系统就会重复创建订单。等等......场景。这时,分布式共享锁就闪亮登场了。 
  
共享锁在同一个进程中是很容易实现的,但在跨进程或者在不同Server之间就不好实现了。Zookeeper就很容易实现。具体的实现原理官网和其它网站也有翻译,这里就不在赘述了。 
  
官</div>
                                </li>
                                <li><a href="/article/3668.htm"
                                       title="两个容易被忽略的MySQL知识" target="_blank">两个容易被忽略的MySQL知识</a>
                                    <span class="text-muted">tomcat_oracle</span>
<a class="tag" taget="_blank" href="/search/mysql/1.htm">mysql</a>
                                    <div>1、varchar(5)可以存储多少个汉字,多少个字母数字?     相信有好多人应该跟我一样,对这个已经很熟悉了,根据经验我们能很快的做出决定,比如说用varchar(200)去存储url等等,但是,即使你用了很多次也很熟悉了,也有可能对上面的问题做出错误的回答。     这个问题我查了好多资料,有的人说是可以存储5个字符,2.5个汉字(每个汉字占用两个字节的话),有的人说这个要区分版本,5.0</div>
                                </li>
                                <li><a href="/article/3795.htm"
                                       title="zoj 3827 Information Entropy(水题)" target="_blank">zoj 3827 Information Entropy(水题)</a>
                                    <span class="text-muted">阿尔萨斯</span>
<a class="tag" taget="_blank" href="/search/format/1.htm">format</a>
                                    <div> 题目链接:zoj 3827 Information Entropy 
 题目大意:三种底,计算和。 
 解题思路:调用库函数就可以直接算了,不过要注意Pi = 0的时候,不过它题目里居然也讲了。。。limp→0+plogb(p)=0,因为p是logp的高阶。 
#include <cstdio>
#include <cstring>
#include <cmath&</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>