WEBPACK4+BABEL7+REACT 组件打包
概述
由于最近项目需求,需要在原有架构上添加新功能模块。新功能模块基于react开发。
大部分react单页应用使用 Create React App 这个脚手架进行初始化。由于本项目需要将其封装为模块,故需要自定义打包部分,将css js 单独打包为引用文件,以此为基础二次调用。
依赖环境安装
webpack4
由于本机已有其他使用打包的程序,webpack4 为全局安装选项。4版本中cli需要单独安装。
npm i webpack webpack-cli -g
babel 及相关组件
官网示例中使用了babel6版本。官网DEMO
官网版本示例中 安装示例
npm install babel-cli@6 babel-preset-react-app@3
官网版本中处理jsx文件示例
npx babel --watch src --out-dir . --presets react-app/prod
但由于当前需求比较复杂,而本机babel环境为7版本。故本次打包也使用7版本babel。
7版本babel中对各组件命名和内容都有了一系列的修改。升级后带@的组件,大体上为babel7版本组件。
安装babel及相关
npm i @babel/cli @babel/core @babel/preset-env @babel/preset-react -D
安装后 package.json内容如下
"devDependencies": {
"@babel/cli": "^7.8.4",
"@babel/core": "^7.9.0",
"@babel/preset-env": "^7.9.5",
"@babel/preset-react": "^7.9.4"
}
安装 babel-loader
npm i babel-loader -D
以上安装好之后,就可以进行初步的配置文件编写了。
webpack配置
webpack配置文件为 webpack.config.js
REACT组件打包
- 使用 @babel/preset-env 进行 ES6 转码
- 使用 @babel/preset-react React 转码
const path = require('path')
module.exports = {
// 入口文件
entry: './src/index.js',
// 打包模式
mode: 'development',
resolve: {
// 解析顺序
extensions: ['.js', '.jsx', '.scss', '.css']
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env', '@babel/preset-react']
}
}],
exclude: /node_modules/
}
]
},
output: {
// 输出文件目录
path: path.resolve(__dirname, 'dist'),
// 输出文件名称 -打包需求不需要hash码 此处可以加hash
filename: 'index.js'
}
}
至此完成 对index.js 和REACT相关引用的配置。
scss 自动化打包
由于组件调用需求 css为单独引用部分。故希望在各自独立组件打包时,也进行同步打包。
由于 webpack 4 与 extract-text-webpack-plugin目前还有兼容问题,又不想使用bate版本。故使用mini-css-extract-plugin插件对scss和 css进行打包。
安装打包组件包
npm i mini-css-extract-plugin autoprefixer css-loader node-sass postcss-loader sass-loader style-loader -D
安装后 package.json 内容增加
{
"autoprefixer": "^9.7.6",
"babel-loader": "^8.1.0",
"css-loader": "^3.5.1",
"mini-css-extract-plugin": "^0.9.0",
"node-sass": "^4.13.1",
"postcss-loader": "^3.0.0",
"sass-loader": "^8.0.2",
"style-loader": "^1.1.3"
}
配置插件,参数中没有路径选项,但是实测可以在filename中带入路径。
const extractSass = new MiniCssExtractPlugin({
filename: '/css/index.css'
})
在rule中添加
{
test: /\.(css|sass|scss)$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
importLoaders: 2,
sourceMap: true
}
},
{
loader: 'postcss-loader',
options: {
plugins: () => [require('autoprefixer')],
sourceMap: true
}
},
{
loader: 'sass-loader',
options: {
sourceMap: true
}
}
],
exclude: /node_modules/
}
加入插件
plugins: [extractSass]
配置后的整体配置文件
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const path = require('path')
const extractSass = new MiniCssExtractPlugin({
filename: '/css/index.css'
})
module.exports = {
entry: './src/index.js',
mode: 'development',
resolve: {
extensions: ['.js', '.jsx', '.scss', '.css']
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env', '@babel/preset-react']
}
},
{
test: /\.(css|sass|scss)$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
// publicPath: 'css',
importLoaders: 2,
sourceMap: true
}
},
{
loader: 'postcss-loader',
options: {
plugins: () => [require('autoprefixer')],
sourceMap: true
}
},
{
loader: 'sass-loader',
options: {
sourceMap: true
}
}
],
exclude: /node_modules/
}
]
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'index.js'
},
plugins: [extractSass]
}
以上 运行 webpack 或者 webpack --wacth 就可以完成对组件的打包。
打包结果测试
建立 index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Add React in One Minute</title>
</head>
<body>
<h2>Add React in One Minute</h2>
<p>This page demonstrates using React with no build tooling.</p>
<p>React is loaded as a script tag.</p>
<!-- 将放置React组件在这个div中 -->
<div id="like_button_container"></div>
<!-- 加载React. -->
<!-- 注意: 在生产环境部署时, 需要替换 "development.js" 为"production.min.js". -->
<script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
<!-- 加载我们的 React组件. -->
<link rel="stylesheet" href="../dist/css/index.css">
<script src="../dist/index.js"></script>
</body>
</html>