开始前
webpack:一个前端资源加载/打包工具
项目中需要处理的文件一般会使用的插件:
- html: html-webpack-plugin (把html单独打包成文件,把对应的脚本和样式插入到合适的位置)、html-loader
- 脚本: babel+babel-preset-react (解析ES6,JSX)
- 样式:css-loader+sass-loader
- 图片、字体: url-loader+file-loader
- extract-text-webpack-plugin:把样式提取出来,打包成单独文件
- CommonChunkPlugin:webpack自带,提取通用模块
- webpack-dev-server:为webpack项目提供web服务,监听文件改动自动刷新,路径代理转发。
环境准备
node、cnpm/yarn,创建一个react-test(随便起)空目录存放项目文件
初始化工程,创建pakage.json
cd react-test
npm init
安装webpack
npm install webpack webpack-cli --save-dev(请安装webpack v3的版本,最新v4有些插件不兼容,会出现坑)
–save-dev与–save的区别
- –save-dev: 打包的时候不会打包到源码中去,就是说是在开发的时候使用到。例如webpack,babel等
- –save : 安装代码允许必须的库,发布时需要依赖的包,例如react,react-route-dom
新建和配置webpack
在react-test目录创建webpack.config.js文件:
mkdir webpack.config.js
写入相关配置
const path = require('path');
module.exports = {
entry: './src/app.jsx', //入口文件
output: { //输出文件
// path:生成的文件要放在哪个位置
// __dirname是node.js中的一个全局变量,它指向当前执行脚本所在的目录
path: path.resolve(__dirname, 'dist'),
filename: 'js/app.js' // 生成文件的名称
}
}
因为我这里webpack不是全局安装的,所以可以在控制台直接通过 .\node_modules\.bin\webpack 命令来运行打包。
打包成功后就可以在根目录看到一个dist文件,里面包含新生产的js文件。
配置web服务器
- 不再使用.\node_modules.bin\webpack打包,安装webpack-dev-server
npm install webpack-dev-server --save-dev
- 配置devServer
//webpack.config.js
module.exports = {
entry: './src/app.jsx', //入口文件
output: { //输出文件
// path:生成的文件要放在哪个位置
// __dirname是node.js中的一个全局变量,它指向当前执行脚本所在的目录
path: path.resolve(__dirname, 'dist'),
filename: 'js/app.js' // 生成文件的名称
},
devServer:{
port: 8086
}
}
//package.json
"scripts": {
"dev": "node_modules/.bin/webpack-dev-server"
},
接着,就可以在控制台输入 npm run dev 运行项目,地址:http://localhost:8086
安装babel和react
接下来代码中会用到ES6的语法和jsx,所以先把babel和react装上
npm insatll react react-dom react-router-dom --save
npm install @babel/core babel-loader @babel/preset-env @babel/preset-react --save-dev
在安装成功后必须进行babel的配置,在根目录react-test建立.babelrc文件,然后写入以下配置
{
"presets": ["@babel/preset-env", "@babel/preset-react"]
}
接着,在webpack.config.js 的module中添加rules规则
module:{
rules:[
{
test: /\.(js|jsx)$/,
exclude: /(node_modules)/, //排除node_modules
use: {
loader: 'babel-loader',
}
}
]
}
安装其他需要的插件
- 首先,现在src目录下创建app.jsx、index.html。
index.html结构:
app.jsx:
import React from 'react';
import ReactDOM from 'react-dom';
class App extends React.Component{
render(){
return <p>测试的组件</p>
}
}
ReactDOM.render(
<App />,
document.getElementById('app')
)
- 处理html
安装html-webpack-plugin和html-loader
npm install html-webpack-plugin html-loader --save-dev
配置规则:
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/app.jsx', //入口文件
output: { //输出文件
//path:生成的文件要放在哪个位置 __dirname是node.js中的一个全局变量,它指向当前执行脚本所在的目录
path: path.resolve(__dirname, 'dist'),
filename: 'js/app.js' // 生成文件的名称
},
module:{
rules: [
{
test: /\.(js|jsx)$/,
exclude: /(node_modules)/,
use: {
loader: 'babel-loader',
}
},
{
test: /\.html$/,
use: {
loader: 'html-loader'
}
},
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
})
]
}
- 处理样式
安装css-loader,style-loader,sass-loader
npm install style-loader css-loader --save-dev
npm install sass-loader node-sass --save-dev
配置规则,把代码放到rules里面:
{
test: /\.css$/,
use: [ 'style-loader', 'css-loader' ]
},
{
test: /\.scss$/,
use: [{
loader: "style-loader" // 将 JS 字符串生成为 style 节点
}, {
loader: "css-loader" // 将 CSS 转化成 CommonJS 模块
}, {
loader: "sass-loader" // 将 Sass 编译成 CSS
}]
},
我们可以在src目录下创建一个index.scss,style.css,并且写上样式。接着在app.jsx文件中引入
import './style.css';
import './index.scss';
// index.scss的样式
p{
font-size:30px;
color: red;
}
//style.css的样式
body{
padding:0;
margin:0;
background-color: pink;
}
最后运行 npm run dev打包
打开http://localhost:8086,就可以看到效果了,eg:
4. 但是我们现在打包的css是包含在打包后的dist/js/app.js文件里面的,所以我们要把它抽取出来。使用到的是extract-text-webpack-plugin插件
- 安装和配置extract-text-webpack-plugin
- npm install extract-text-webpack-plugin --save-dev
- 在安装这里遇到了一个坑。因为我之前安装的是webpack v4的版本。安装的extract-text-webpack-plugin插件又不是最新的,所以打包出错,提示:Tapable.plugin is deprecated. Use new API on
.hooks
instead 。 - 解决方法 : 卸载之前安装的extract-text-webpack-plugin插件。重新安装最新的extract-text-webpack-plugin插件:·
npm install extract-text-webpack-plugin@next --save-dev
;或者直接安装webpack v3的版本 - 配置,具体可参照webpack官网上的用法:https://www.webpackjs.com/plugins/extract-text-webpack-plugin/
// 1、引入extract-text-webpack-plugin
const ExtractTextPlugin = require('extrack-text-webpack-plugin');
// 2、在plugin中创建ExtractTextPlugin实例
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
}),
new ExtractTextPlugin("css/[name].css") //提取css
]
// 3、修改之前的css,scss规则
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: "css-loader"
})
},
{
test: /\.scss$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: ['css-loader', 'sass-loader']
})
},
- 顺便把js的公共代码提取出来,因为我这里用的是webpack4, CommonChunkPlugin已被弃用,改用SplitChunksPlugin,详细可以查看webpack文档。我这里也把CommonChunkPlugin的方法写出来。
const webpack = require('webpack');
//CommonChunkPlugin:在plugin中创建实例
plugins: [
//处理html文件
new HtmlWebpackPlugin({
template: 'src/index.html'
}),
//独立css文件
new ExtractTextPlugin("css/[name].css"),
//提出公共模块
new webpack.optimize.CommonsChunkPlugin({
name: 'common',
filename: 'js/base.js'
})
],
//SplitChunksPlugin:
optimization:{
splitChunks: {
cacheGroups: {
vendor: {
name: "vendor",
test: /[\\/]node_modules[\\/]/, //打包第三方库
chunks: "all",
priority: 10 // 优先级
},
commons: { // 打包其余的的公共代码
name: "commons", // 分离包的名字
chunks: "initial",
minChunks: 2 // 引入两次及以上被打包
}
}
}
}
- 处理静态文件
- 安装file-loader和url-loader
npm install file-loader url-loader --save-dev
- 因为编译后文件是在dist中,所以要修改一下output,可以自动更新内嵌的url值
output: {
path: path.resolve(__dirname, 'dist'),
publicPath: '/dist/', //指定资源文件引用的目录
filename: 'js/app.js'
},
- 配置rules
{
test: /\.(png|jpg|gif)$/i,
use: [
{
loader: 'url-loader', //使用
options: {
limit: 8192,
name: 'resource/[name].[ext]'
},
},
],
},
- 配置别名
- 在写代码的时候,我们需要引入不同文件夹下的组件。引入的路径会写的比较长,为了减少路径的复杂度,我们可以在webpack中配置别名
module.exports = {
........
resolve:{
alias:{
page: path.resolve(__dirname, 'src/page')
}
},
}
// 使用:
import Test from 'page/home/index.jsx'
结束
关于react的webpack配置还有很多,例如代理,配置字体规则等等,在实际的项目中按需要去添加。
大家一起学习进步,加油!