项目初始化
$ npm init
安装webpack
本次创建是基于webpack4
$ npm install --save-dev
新建webpack配置文件
在根目录创建build文件夹,添加一个js文件,命名为webpack.base.conf.js
// webpack.base.conf.js 文件
const path = require(\'path\');
const DIST_PATH = path.resolve(__dirname, \'../dist\');
module.exports = {
entry: {
app: \'./app/index.js\'
},
output: {
filename: \"js/bundle.js\",
path: DIST_PATH
}
};
使用merge的方式来组织webpack基础配置和不同环境的配置
先安装webpack-merge:
$ npm install --save-dev webpack-merge
在build文件夹中再添加一个js文件,命名为 webpack.prod.conf.js
// webpack.prod.conf.js 文件
const merge = require(\'webpack-merge\');
const baseWebpackConfig = require(\'./webpack.base.conf\');
module.exports = merge(baseWebpackConfig, {
mode: \'production\'
});
在根目录下创建app目录,然后创建index.js文件
var element =document.getElementById(\'root\'); element.innerHTML = \'hello, world!\';
在根目录创建一个public文件夹,然后新建一个index.html文件
// index.html
<!DOCTYPE html>
<html lang=\"en\">
<head>
<meta charset=\"UTF-8\">
<title>从零开始搭建react工程</title>
</head>
<body>
<div id=\"root\"></div>
<script src=\"../dist/js/bundle.js\"></script>
</body>
</html>
当前项目目录树
|- /app |- index.js |- /node_modules |- /public |- index.html |- /build |- webpack.base.conf.js |- webpack.prod.conf.js |- package.json |- package-lock.json
安装webpack-cli
webpack 4.0 版本之后的webpack,已经将webpack命令工具迁移到webpack-cli模块了,需要安装 webpack-cli
$ npm install --save-dev webpack-cli
package.json文件 scripts属性配置一个build命令
其值为:webpack --config build/webpack.prod.conf.js,以下是scripts的相关代码
// package.json
\"scripts\": {
\"build\": \"webpack --config build/webpack.prod.conf.js\",
\"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"
},
安装React
$ npm install --save react react-dom
修改app目录下的index.js的代码
import React from \"react\"; import ReactDom from \"react-dom\"; ReactDom.render( <h1>hello, world!</h1>, document.getElementById(\"root\") );
注意 import 属于ES6规范,因此需要转译ES2015+的语法,安装并配置 babel 以及相关依赖
$ npm install --save-dev babel-loader babel-core babel-preset-env babel-preset-react
根目录创建.babelrc文件,配置presets.
{
\"presets\": [
[
\"env\",
{
\"targets\": {
\"browsers\": [
\"> 1%\",
\"last 5 versions\",
\"ie >= 8\"
]
}
}
],
\"react\"
]
}
修改webpack.base.conf.js文件
// webpack.base.conf.js
const path = require(\'path\');
const APP_PATH = path.resolve(__dirname, \'../app\');
const DIST_PATH = path.resolve(__dirname, \'../dist\');
module.exports = {
entry: {
app: \'./app/index.js\'
},
output: {
filename: \'js/bundle.js\',
path: DIST_PATH
},
module: {
rules: [
{
test: /\\.js?$/,
use: \"babel-loader\",
include: APP_PATH
}
]
}
};
运行 npm run build
添加插件
public下的index.html本该自动添加到dist目录,并且引用资源自动加载到该文件,通过html-webpack-plugin实现这一步
$ npm install html-webpack-plugin --save-dev
webpack.prod.conf.js中配置plugins属性
const merge = require(\'webpack-merge\');
const baseWebpackConfig = require(\'./webpack.base.conf.js\');
const HtmlWebpackPlugin = require(\'html-webpack-plugin\');
module.exports = merge(baseWebpackConfig, {
mode: \'production\',
plugins: [
new HtmlWebpackPlugin({
template: \'public/index.html\',
inject: \'body\',
minify: {
removeComments: true,
collapseWhitespace: true,
removeAttributeQuotes: true
},
})
]
});
删除 index.html 中手动引入的 script 标签
<!DOCTYPE html> <html lang=\"en\"> <head> <meta charset=\"UTF-8\"> <title>从零开始搭建react工程</title> </head> <body> <div id=\"root\"></div> </body> </html>
重新编译查看 npm run build 浏览器打开查看目录 dist 下的 index.html
以上步骤都成功的前提下继续走下一步
生成的文件名添加Hash值,目的是解决缓存问题
修改webpack.prod.conf.js,mode: \'production\', 增加以下代码
// webpack.prod.conf.js
output: {
filename: \"js/[name].[chunkhash:16].js\",
},
生成前需要清理之前项目生成的文件,因为由于文件名的改变如果不删除会一直增加
安装插件 clean-webpack-plugin
$ npm install --save-dev clean-webpack-plugin
修改 webpack.prod.conf.js
// webpack.prod.conf.js
const merge = require(\'webpack-merge\');
const baseWebpackConfig = require(\'./webpack.base.conf.js\');
const HtmlWebpackPlugin = require(\'html-webpack-plugin\');
const CleanWebpackPlugin = require(\'clean-webpack-plugin\');
module.exports = merge(baseWebpackConfig, {
mode: \'production\',
output: {
filename: \"js/[name].[chunkhash:16].js\",
},
plugins: [
new HtmlWebpackPlugin({
template: \'public/index.html\',
inject: \'body\',
minify: {
removeComments: true,
collapseWhitespace: true,
removeAttributeQuotes: true
},
}),
new CleanWebpackPlugin([\'../dist\'], { allowExternal: true })
]
});
公共代码与业务代码分离
修改 webpack.base.conf.js 的 entry 入口属性,抽出框架代码
entry: {
app: \'./app/index.js\',
framework: [\'react\',\'react-dom\'],
},
修改webpack.prod.conf.js,增加以下代码,目的是分离框架代码和业务代码
虽然上面步骤抽出框架代码生成两个文件,但是app.js还是包含框架代码
optimization: {
splitChunks: {
chunks: \"all\",
minChunks: 1,
minSize: 0,
cacheGroups: {
framework: {
test: \"framework\",
name: \"framework\",
enforce: true
}
}
}
}
cacheGroups对象,定义了需要被抽离的模块
其中test属性是比较关键的一个值,他可以是一个字符串,也可以是正则表达式,还可以是函数。如果定义的是字符串,会匹配入口模块名称,会从其他模块中把包含这个模块的抽离出来
name是抽离后生成的名字,和入口文件模块名称相同,这样抽离出来的新生成的framework模块会覆盖被抽离的framework模块
整合 webpack-dev-server
开发环境开启服务监听文件改动实时更新最新内容
$ npm install --save-dev webpack-dev-server
在build中添加webpack.dev.conf.js文件
const path = require(\'path\');
const merge = require(\'webpack-merge\');
const baseWebpackConfig = require(\'./webpack.base.conf.js\');
const HtmlWebpackPlugin = require(\'html-webpack-plugin\');
const webpack = require(\'webpack\');
module.exports = merge(baseWebpackConfig, {
mode: \'development\',
output: {
filename: \"js/[name].[hash:16].js\",
},
plugins: [
new HtmlWebpackPlugin({
template: \'public/index.html\',
inject: \'body\',
minify: {
html5: true
},
hash: false
}),
new webpack.HotModuleReplacementPlugin()
],
devServer: {
port: \'8080\',
contentBase: path.join(__dirname, \'../public\'),
compress: true,
historyApiFallback: true,
hot: true,
https: false,
noInfo: true,
open: true,
proxy: {}
}
});
在package.json scripts属性添加内容
\"dev\": \"webpack-dev-server --inline --progress --config build/webpack.dev.conf.js\",
npm run dev
自动打开浏览器打开入口页面实时更新
独立导出 css 文件
安装css相关依赖
sass less 预处理
$ npm install extract-text-webpack-plugin $ npm install style-loader css-loader postcss-loader autoprefixer --save-dev $ npm install less sass less-loader sass-loader stylus-loader node-sass --save-dev
webpack.base.conf.js 文件修改
// webpack.base.conf.js
{
test: /\\.css$/,
use: [
{
loader: \"style-loader\" //在html中插入<style>标签
},
{
loader: \"css-loader\",//获取引用资源,如@import,url()
},
{
loader: \"postcss-loader\",
options: {
plugins:[
require(\'autoprefixer\')({
browsers:[\'last 5 version\']
})
]
}
}
]
},
{
test:/\\.less$/,
use: [
{ loader: \"style-loader\" },
{ loader: \"css-loader\" },
{
loader: \"postcss-loader\",//自动加前缀
options: {
plugins:[
require(\'autoprefixer\')({
browsers:[\'last 5 version\']
})
]
}
},
{ loader: \"less-loader\" }
]
},
{
test:/\\.scss$/,
use:[
{ loader: \"style-loader\" },
{
loader: \"css-loader\",
},
{ loader: \"sass-loader\" },
{
loader: \"postcss-loader\",
options: {
plugins:[
require(\'autoprefixer\')({
browsers:[\'last 5 version\']
})
]
}
}
]
},
图片和路径处理
$ npm i file-loader url-loader --save-dev
webpack.base.conf.js 文件修改
// webpack.base.conf.js
{
test: /\\.(png|jpg|gif|woff|svg|eot|woff2|tff)$/,
use: \'url-loader?limit=8129\',
//注意后面那个limit的参数,当你图片大小小于这个限制的时候,会自动启用base64编码图片
exclude: /node_modules/
}
build 时报错
Error: Chunk.entrypoints: Use Chunks.groupsIterable and filter by instanceof Entrypoint instead
at Chunk.get (F:\\react\\createApp\\node_modules\\webpack\\lib\\Chunk.js:824:9)
webpack4.0中使用“extract-text-webpack-plugin”报错
解决办法
$ npm install extract-text-webpack-plugin@next
背景图片路径问题
由于css文件分离出来的原因,会导致在css文件夹下找images文件夹下的图片
解决办法 publicPath属性改为 \'/\',以绝对路径的方式寻找资源
{
test:/\\.(png|jpg|gif)$/,
use:[{
loader:\'url-loader\',
options: {
// outputPath:\'../\',//输出**文件夹
publicPath: \'/\',
name: \"images/[name].[ext]\",
limit:500 //是把小于500B的文件打成Base64的格式,写入JS
}
}]
},
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
版权声明
本文仅代表作者观点,不代表百度立场。
本文系作者授权百度百家发表,未经许可,不得转载。


