简易版webpack搭建react

参考资源:

https://www.jianshu.com/p/8f49aaa6169e

https://www.jianshu.com/p/bcad129a1c69

初始化文件npm install 

全局安装webpack npm install webpack -g

添加src文件夹,创建index.js文件,下面对index.js文件内容进行打包

在webpack.config.js下对webpack打包出入路径进行设置

const path = require('path');//路径解析

module.exports = {
  entry: './src/index.js', // 打包入口文件
  mode: 'development',
  output: {
    path: path.resolve(__dirname, 'build'), // 打包路径到build文件夹下
    filename: 'bundle.js', // 生成打包文件名
  },

};

package.json中script下添加 "build": "webpack --config webpack.config.js"//通过--config进行文件配置,后续可通过npm run build进行打包

package.json中script下添加"dev": "webpack-dev-server"实现npm run dev后在浏览器下起服务查看的效果,默认url是 http://localhost:8080/,此时有一个问题就是输入对应路径后打开的是对应根路径,而不是index页面

为了让页面打开就可以显示html文件入口,需要结合webpack-dev-server配置devServer

devServer: {
    port: 3000,
    contentBase: './bundle',
    hot: true,
  },

src下添加index.html,引入html-webpack-plugin插件

先安装 npm install html-webpack-plugin,并进行如下配置

const path = require('path');
const HtmlPlugin = require('html-webpack-plugin');

module.exports = {
  entry: './src/index.js', // 打包入口文件
  mode: 'development',
  output: {
    path: path.resolve(__dirname, 'build'), // 打包路径到build文件夹下
    filename: 'bundle.js', // 生成打包文件名
  },
  plugins: [
    new HtmlPlugin({ // 生成html文件入口
      template: './public/index.html', // 源模板文件,打包后生成的html文件是以'./public/index.html'文件作为主入口并进行打包
      filename: 'index.html', // 打包后生成的html文件名
      minify: {
        collapseWhitespace: true, // 折叠html文件中的空行
        removeAttributeQuotes: true, // 删除双引号
        removeComments: true, // 去掉注释
      },
    }),
  ],

};

build后再dev页面可以看见刚进入打开的是对应index.html文件内容

对于内部css文件需要使用css-loader对@import外联样式和url()引入进行css转换,同时还需要配置style-loader将css插入到dom中

并在webpack.config.js下进行loader配置,在此过程中也可能会用到css相关预处理器比如less、sass等,需要引入相应loader进行css转换;也可以添加postcss-loader配合autoprefixer给css样式添加前缀实现兼容处理,需要注意的是要需要新建一个postCss.config.js文件将autoprefixer插件引入

module: {
    rules: [
      {
        test: /\.css$/, // 匹配.css文件
        use: ['style-loader', 'css-loader', 'postcss-loader'], // 从右向左进行顺序转换
      },
      {
        test: /\.less$/, // 匹配.css文件
        use: ['style-loader', 'css-loader', 'less-loader', 'postcss-loader'], // 从右向左进行顺序转换
      },
    ],
  },



//postCss.config.js
module.exports = {
  plugins: [
    require('autoprefixer'),
  ],
};

此时可能遇到一个问题:没有添加前缀,解决办法:在package.json文件中添加

"browserslist": [
  "iOS >= 6",
  "Android >= 4",
  "IE >= 9"
],

如果想把自定义样式放到head中 :需要在style-loader初设置insert:'top'

使用mini-css-extract-plugin将css文件提取为独立的css文件(将style-loader替换成MiniCssPlugin.loader),同时添加optimize-css-assets-webpack-plugin插件压缩css文件

const path = require('path');
const HtmlPlugin = require('html-webpack-plugin');
const MiniCssPlugin = require('mini-css-extract-plugin');
const OptimizecssPlugin = require('optimize-css-assets-webpack-plugin');

module.exports = {
  entry: './src/index.js', // 打包入口文件
  mode: 'development',
  output: {
    path: path.resolve(__dirname, 'build'), // 打包路径到build文件夹下
    filename: 'bundle.js', // 生成打包文件名
  },
  plugins: [
    new HtmlPlugin({ // 生成html文件入口
      template: './public/index.html', // 源模板文件,打包后生成的html文件是以'./public/index.html'文件作为主入口并进行打包
      filename: 'index.html', // 打包后生成的html文件名
      minify: {
        collapseWhitespace: true, // 折叠html文件中的空行
        removeAttributeQuotes: true, // 删除双引号
        removeComments: true, // 去掉注释
      },
    }),
    new MiniCssPlugin({
      filename: 'main.css',
    }),
    new OptimizecssPlugin({}),
  ],
  module: {
    rules: [
      {
        test: /\.js$/, // 匹配.css文件
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env', '@babel/preset-react'],
            include: path.resolve(__dirname, 'src'),
          },

        },
      },
      {
        test: /\.css$/, // 匹配.css文件
        use: [MiniCssPlugin.loader, 'css-loader', 'postcss-loader'], // 从右向左进行顺序转换
      },
      {
        test: /\.less$/, // 匹配.css文件
        use: [MiniCssPlugin.loader,'css-loader', 'less-loader', 'postcss-loader'], // 从右向左进行顺序转换
      },

    ],
  },
};

 

安装react react-dom 进行react脚手架搭建npm install react react-dom --save-dev

修改入口文件index.js写成组件形式,高级语言无法被浏览器识别,需要引入babel-loader进行转译成es5,同时针对es5以及jsx语法还需要使用 @babel/preset-react和@babel/preset-react

      {
        test: /\.js$/, // 匹配.css文件
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env', '@babel/preset-react'],
            include: path.resolve(__dirname, 'src'),
          },

        },
      },

修改index.js中文件,同时在index.html下添加js(一般是id='root')插入的根节点

///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>
    <style>
      body {
        background: pink;
      }
    </style>
  </head>
  <body>
    <div id="root"></div>
  </body>
</html>

///index.js
import React, { Component } from 'react';
import ReactDom from 'react-dom';

const a = require('./a');
require('./body.css');
require('./a.less');

class App extends Component {
  render() {
    return <h1> Hello, world! </h1>;
  }
}

ReactDom.render(
  <App />,
  document.getElementById('root'),
);

图片需要使用url-loader或file-loader进行转换,对于不超过limit限制大小的图片使用url-loader可以将图片转为base64形式减少http请求,超过限制大小的自动使用file-loader来进行转换,url-loader也可以用来转换字体

      {
        test: [/\.jpe?g$/, /\.gif$/, /.\png$/],
        use: {
          loader: 'url-loader',
          options: {
            limit: 10000, // 10000B 对照1024差不多9点几kb
            name: 'image/[name]_[hash].[ext]',
          },
        },
      },

热更新主要基于webpack-dev-derver实现,webpack-dev-derver会自动刷新页面

实现热更新第一步需要在devServer中开启热更新开关hot:true

之后可以添加HotModuleReplacementPlugin插件或是在package的"dev"内添加 --hot(需要注意的是,两者任选一,否则会报错: Maximum call stack size exceeded)

但是我们想要的效果是不刷新页面的同时替换旧模块,简单配置一个hot随意更改一下dom会发现页面还是自己自动刷新了,这个时候需要结合module.hot,对于不需要自动刷新部分使用module.hot.accept()

if (module.hot) {
  module.hot.accept(() => {
    ReactDom.render(
      <App />,
      document.getElementById('root'),
    );
  });
}
ReactDom.render(
  <App />,
  document.getElementById('root'),
);

平时我们npm run dev后就会自动打开,这个可以在package.json下添加--open

 "dev": "webpack-dev-server --hot --open"

在更新css样式的时候发现修改样式并没有同步更新,此时可以引入css-hot-loader实时更新css样式

      {
        test: /\.css$/, // 匹配.css文件
        use: ['css-hot-loader',
          MiniCssPlugin.loader, 'css-loader', 'postcss-loader'], // 从右向左进行顺序转换
      },
      {
        test: /\.less$/, // 匹配.css文件
        use: ['css-hot-loader', MiniCssPlugin.loader, 'css-loader', 'less-loader', 'postcss-loader'], // 从右向左进行顺序转换
      },

在写箭头函数时需要在babel-loader下添加@babel/plugin-proposal-class-properties编译类

      {
        test: /\.js$/, // 匹配.js文件
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env', '@babel/preset-react'],
            include: path.resolve(__dirname, 'src'),
            plugins: [
              '@babel/plugin-proposal-class-properties',
            ],
          },

        },
      },

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值