react打包后图片丢失_webpack实战第二篇(搭建react开发环境)

10b07e22ff7bf06b0166b563189a9331.png

第一篇基础部分可以参考上一篇文章

林海:webpack实战第一篇(基础部分)​zhuanlan.zhihu.com
fb9e0b009912767a50be8ea9dd3c5913.png

第一篇已经教会我们搭建了webpack的基础环境,这一篇我们来搭建一个基于react的项目

1.1 搭建react开发环境

react相关库

npm i react react-dom 

解析react的库

 npm i -D @babel/preset-react 

此时,我们的webpack把js的配置改为jsx的

 {
   test: /(.jsx|.js)/,
   use:{
   loader:'babel-loader',
   options:{
   presets:['@babel/preset-env','@babel/preset-react']
            }
          },
   exclude:/node_modules/
 },

1.2 配置webpack-dev-server进行热更新

npm i -D webpack-dev-server

配置如下

const Webpack = require('webpack')
module.exports = {
  // ...省略其他配置
  devServer:{
    port:3000,
    hot:true,
    contentBase:'../dist'
  },
  plugins:[
    new Webpack.HotModuleReplacementPlugin()
  ]
}

完整配置如下

// webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin')
const {CleanWebpackPlugin} = require('clean-webpack-plugin')
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const Webpack = require('webpack')
module.exports = {
 mode:'development', // 开发模式
 entry: ["@babel/polyfill",path.resolve(__dirname,'../src/index.jsx')], 
 output: {
 filename: '[name].[hash:8].js',      // 打包后的文件名称
 path: path.resolve(__dirname,'../dist')  // 打包后的目录
    },
 devServer:{
 port:3000,
 hot:true,
 contentBase:'../dist'
    },
 resolve:{
 alias:{
 'react':'react',
 '@':path.resolve(__dirname,'../src')
      },
 extensions:['*','.js','.json','.jsx']
    },
 module:{
 rules:[
          {
 test:/.css$/,
 use:['style-loader',MiniCssExtractPlugin.loader,'css-loader'] // 从右向左解析原则
          },
          {
 test:/.less$/,
 use:['style-loader',MiniCssExtractPlugin.loader,'css-loader',{
 loader:'postcss-loader',
 options:{
 plugins:[require('autoprefixer')]
                }
            },'less-loader'] // 从右向左解析原则
        },
        {
 test: /.(jpe?g|png|gif)$/i, //图片文件
 use: [
            {
 loader: 'url-loader',
 options: {
 limit: 10240,
 fallback: {
 loader: 'file-loader',
 options: {
 name: 'img/[name].[hash:8].[ext]'
                  }
                }
              }
            }
          ]
        },
        {
 test: /.(mp4|webm|ogg|mp3|wav|flac|aac)(?.*)?$/, //媒体文件
 use: [
            {
 loader: 'url-loader',
 options: {
 limit: 10240,
 fallback: {
 loader: 'file-loader',
 options: {
 name: 'media/[name].[hash:8].[ext]'
                  }
                }
              }
            }
          ]
        },
        {
 test: /.(woff2?|eot|ttf|otf)(?.*)?$/i, // 字体
 use: [
            {
 loader: 'url-loader',
 options: {
 limit: 10240,
 fallback: {
 loader: 'file-loader',
 options: {
 name: 'fonts/[name].[hash:8].[ext]'
                  }
                }
              }
            }
          ]
        },
        {
 test: /(.jsx|.js)/,
 use:{
 loader:'babel-loader',
 options:{
 presets:['@babel/preset-env','@babel/preset-react']
            }
          },
 exclude:/node_modules/
        },
        ]
      },
 plugins:[
 new HtmlWebpackPlugin({
 template:path.resolve(__dirname,'../public/index.html')
        }),
 new CleanWebpackPlugin(),
 new MiniCssExtractPlugin({
 filename: "[name].[hash].css",
 chunkFilename: "[id].css",
        }),
 new Webpack.HotModuleReplacementPlugin()
    ],
}

1.3 配置dev命令

  "scripts": {
    "build": "webpack --config build/webpack.config.js",
    "dev": "webpack-dev-server --config build/webpack.config.js --open"
  },

index.html加入一个根节点

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <meta http-equiv="X-UA-Compatible" content="ie=edge">
 <title>Document</title>
</head>
<body>
 <div id="react-root"></div>
</body>
</html>

index.jsx

import "./assets/index.css"
import "./assets/index.less"
import React from "react"
import * as ReactDom from "react-dom"

ReactDom.render(
 <div>渲染成功</div>, window.document.getElementById("react-root"),
  );
 

运行npm run dev

5f4acf93cdbf363b67a68c6c9947b024.png

执行npm run dev这时候如果浏览器出现Vue开发环境运行成功,那么恭喜你,已经成功迈出了第一步

1.4 区分开发环境与生产环境

实际应用到项目中,我们需要区分开发环境与生产环境,我们在原来webpack.config.js的基础上再新增两个文件

  • webpack.dev.js 开发环境配置文件
开发环境主要实现的是热更新,不要压缩代码,完整的sourceMap

webpack.prod.js生产环境配置文件

生产环境主要实现的是压缩代码、提取css文件、合理的sourceMap、分割代码 需要安装以下模块: npm i -D webpack-merge copy-webpack-plugin optimize-css-assets-webpack-plugin uglifyjs-webpack-plugin
  • webpack-merge 合并配置
  • copy-webpack-plugin 拷贝静态资源
  • optimize-css-assets-webpack-plugin 压缩css
  • uglifyjs-webpack-plugin 压缩js
webpack mode设置production的时候会自动压缩js代码。原则上不需要引入uglifyjs-webpack-plugin进行重复工作。但是optimize-css-assets-webpack-plugin压缩css的同时会破坏原有的js压缩,所以这里我们引入uglifyjs进行压缩

这个时候在控制台我们就可以看到我们的react代码了,并且进行调试

48209ef6e9013b3bcf77936f076b6a4d.png

完整配置如下

00969dc33a1074f2493f68c9570499fb.png
// webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin')
const {CleanWebpackPlugin} = require('clean-webpack-plugin')
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const Webpack = require('webpack')
module.exports = {
    mode:'development', // 开发模式
    entry: ["@babel/polyfill",path.resolve(__dirname,'../src/index.jsx')], 
    output: {
      filename: '[name].[hash:8].js',      // 打包后的文件名称
      path: path.resolve(__dirname,'../dist')  // 打包后的目录
    },
    resolve:{
      alias:{
        'react':'react',
        '@':path.resolve(__dirname,'../src')
      },
      extensions:['*','.js','.json','.jsx']
    },
    module:{
        rules:[
          {
            test:/.css$/,
            use:['style-loader',MiniCssExtractPlugin.loader,'css-loader'] // 从右向左解析原则
          },
          {
            test:/.less$/,
            use:['style-loader',MiniCssExtractPlugin.loader,'css-loader',{
                loader:'postcss-loader',
                options:{
                    plugins:[require('autoprefixer')]
                }
            },'less-loader'] // 从右向左解析原则
        },
        {
          test: /.(jpe?g|png|gif)$/i, //图片文件
          use: [
            {
              loader: 'url-loader',
              options: {
                limit: 10240,
                fallback: {
                  loader: 'file-loader',
                  options: {
                      name: 'img/[name].[hash:8].[ext]'
                  }
                }
              }
            }
          ]
        },
        {
          test: /.(mp4|webm|ogg|mp3|wav|flac|aac)(?.*)?$/, //媒体文件
          use: [
            {
              loader: 'url-loader',
              options: {
                limit: 10240,
                fallback: {
                  loader: 'file-loader',
                  options: {
                    name: 'media/[name].[hash:8].[ext]'
                  }
                }
              }
            }
          ]
        },
        {
          test: /.(woff2?|eot|ttf|otf)(?.*)?$/i, // 字体
          use: [
            {
              loader: 'url-loader',
              options: {
                limit: 10240,
                fallback: {
                  loader: 'file-loader',
                  options: {
                    name: 'fonts/[name].[hash:8].[ext]'
                  }
                }
              }
            }
          ]
        },
        {
          test: /(.jsx|.js)/,
          use:{
            loader:'babel-loader',
            options:{
              presets:['@babel/preset-env','@babel/preset-react']
            }
          },
          exclude:/node_modules/
        },
        ]
      },
    plugins:[
        new HtmlWebpackPlugin({
          template:path.resolve(__dirname,'../public/index.html')
        }),
        new CleanWebpackPlugin(),
        new MiniCssExtractPlugin({
          filename: "[name].[hash].css",
          chunkFilename: "[id].css",
        }),
    ],
}

webpack.dev.js

const Webpack = require('webpack')
const webpackConfig = require('./webpack.config.js')
const WebpackMerge = require('webpack-merge')
module.exports = WebpackMerge(webpackConfig,{
 mode:'development',
 devtool:'cheap-module-eval-source-map',
 devServer:{
 port:3000,
 hot:true,
 contentBase:'../dist'
  },
 plugins:[
 new Webpack.HotModuleReplacementPlugin()
  ]
})

webpack.prod.js

const path = require('path')
const webpackConfig = require('./webpack.config.js')
const WebpackMerge = require('webpack-merge')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin')
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
module.exports = WebpackMerge(webpackConfig,{
 mode:'production',
 devtool:'cheap-module-source-map',
 plugins:[
 new CopyWebpackPlugin([{
 from:path.resolve(__dirname,'../public'),
 to:path.resolve(__dirname,'../dist')
    }]),
  ],
 optimization:{
 minimizer:[
 new UglifyJsPlugin({//压缩js
 cache:true,
 parallel:true,
 sourceMap:true
    }),
 new OptimizeCssAssetsPlugin({})
    ],
 splitChunks:{
 chunks:'all',
 cacheGroups:{
 libs: {
 name: "chunk-libs",
 test: /[/]node_modules[/]/,
 priority: 10,
 chunks: "initial" // 只打包初始时依赖的第三方
        }
      }
    }
  }
})

好了,第二篇搭建我们自己的开发环境就结束了,之后第三篇会讲解如何优化我们的webpack

下面是我的webpack第三篇文章,优化我们的webpack

林海:webpack实战第三篇(优化webpack)​zhuanlan.zhihu.com
fb9e0b009912767a50be8ea9dd3c5913.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值