webpack4配置react(开发环境)

安装依赖包

npm init // 新建一个package.json文件
npm i -D webpack webpack-cli webpack-dev-server  // 安装webpack相关
npm i --save react react-dom // 安装react
npm i -D babel-loader @babel/core @babel/preset-env @babel/preset-react // 安装babel相关
npm i -D html-webpack-plugin // 生成html文件
复制代码

这里简单介绍一下babel

babel-loader

babel的编译器,提供转码API,比如transform,babel-loader会直接调用babel-core API对文件进行转码。

@babel/core

文件转码器,简单的说就是将es6 es7转换为让浏览器识别es5。

这里面包括了babel 的核心 api,比如 transform,主要都是处理转码的。它会把我们的 js 代码,抽象成 ast,即 abstract syntax tree(抽象语法树) 的缩写,是源代码的抽象语法结构的树状表现形式。我们可以理解为,它定义的一种分析 js 语法的树状结构。也就是说 es6 的新语法,跟老语法是不一样的,那我们怎么去定义这个语法呢。所以必须要先转成 ast,去发现这个语法的 kind,分别做对应的处理,才能转化成 es5.

@babel/preset-env

可以根据配置的目标运行环境自动启用需要的babel插件,例如对支持的浏览器进行配置:

{
  "targets": {
    "chrome": "58",
    "ie": "11"
  }
}
复制代码

可以在.babelrc文件对babel进行配置。 更多需要了解babel的请点击这里

项目目录

webpack.dev.conf.js

const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin'); // 生成html模板

const resolve = (dir) => path.join(__dirname, '..', dir);

module.exports = {
  mode: 'development', // webpack4新增属性,默认返回production,提供一些默认配置,例如cache:true
  devtool: 'cheap-module-eval-source-map',
  // source-map每个module生成对应的map文件
  // eval 每一个module模块执行eval,不生成map文件,在尾部生成一个sourceURL对应前后关系,所以更快
  // cheap 列信息 VLQ编码
  // module 包含了模块之间的sourcemap
  entry: {
    home: './src/index.js', // 设置入口文件
  },
  output: {
    filename: '[name].js', // 生成的js文件的名字
    path: resolve('dist'), // 生成的js存放目录
  },
  module: { // 配置loader
    rules: [
      {
        test: /\.m?js$/,
        include: resolve('src'), // 只解析src下面的文件,不推荐用exclude
        use: {
          loader: 'babel-loader',
        }
      },
    ],
  },
  devServer: { // 配置webpack-dev-server, 在本地启动一个服务器运行
    host: 'localhost', // 服务器的ip地址 希望服务器外可以访问就设置 0.0.0.0
    port: 8088, // 端口
    open: true, // 自动打开页面
  },
  plugins: [
    new HtmlWebpackPlugin({
      filename: resolve('/dist/index.html'), // 生成的html文件存放的地址和文件名
      template: resolve("/index.html"), // 基于index.html模板进行生成html文件
    }),
  ]
}
复制代码

index.js

import ReactDOM from 'react-dom';
import React from 'react';

ReactDOM.render(
  <h1>表白任素汐!</h1>,
  document.getElementById('root')
)
复制代码

.babelrc

{
  "presets": [
    "@babel/preset-env",
    "@babel/preset-react"
  ],
  "plugins": [
  ]
}
复制代码

index.html

<!DOCTYPE html>
<html lang="en">

  <head>
    <meta charset="utf-8">
    <title>Webpack Sample Project</title>
  </head>

  <body>
    <div id='root'>
    </div>
  </body>

</html>
复制代码

在package.json的scripts添加命令

"dev": "webpack-dev-server --config build/webpack.dev.conf.js",
复制代码

最后在命令行启动,一个最简单的react项目配置好了。

npm run dev
复制代码

模块热更新

webpack通过watch实现热更新,其实就是将我们最后一次修改的时间记录下来,然后定时去监测我们文件的修改时间,发现两者不一样,webpack就会自己去重新创建,我们可以设置监测的间隔时间,以及发现了不同,延长多久去重新构建。(详见webpack WatchOptions

如果改变页面内容,整个页面都会刷新,但是如果模块很多的话,编译就会很慢。模块热更新就是检测代码有没有修改,只将修改的模块进行重新编译,并替换掉之前的模块,这样只有改变的模块才会更新,就像ajax一样局部刷新。

npm install react-hot-loader
npm i -D @babel/plugin-proposal-class-properties // 这个是针对es6 class进行添加的,因为我们新建了home.js文件用了class
复制代码

修改webpack.dev.conf.js

 devServer: {
    hot: true, // 设置热更新(引用react热更新必须设置)
 },
 plugins: [
    new webpack.HotModuleReplacementPlugin(), // 引入热更新插件(引用react热更新必须设置),
 ]
复制代码

.babelrc修改为

{
  "presets": [
    "@babel/preset-react",
    "@babel/preset-env"
  ],
  "plugins": [
    "@babel/plugin-proposal-class-properties",
    "react-hot-loader/babel"
  ]
}
复制代码

新建一个home.js

import React, { Component } from 'react';
import { hot } from 'react-hot-loader';

class App extends Component {
  state = {  }
  render() {
    return (
     <h1>表白任素汐!</h1>
    );
  }
}
export default hot(module)(App);
复制代码

修改index.js

import ReactDOM from 'react-dom';
import React from 'react';
import App from './home';

ReactDOM.render(
  <App />,
  document.getElementById('root')
)
复制代码

npm run dev看看效果吧~

dllplugin 加速神器

随着项目越来越大,我们开发调试的时候,最希望的是节省时间,尽可能快的进行编译。dllplugin借鉴于windows的dll文件,我们可以把一些项目不会改动的存放在一个文件中,每次webpack进行重新编译的时候,我们就可以直接加载,而不用再进行重新编译,就像react,react-dom等项目包。

按照这个思路我们我们再添加一个webpack.dll.config.js文件

const path = require('path')
const webpack = require('webpack')
// 生产环境不用dll的原因是因为很多相同的内容会重复打包的bundles里面
module.exports = {
  entry: {
    vendor: ['react', 'react-dom']
  },
  output: {
    path: path.join(__dirname, '..', 'dist/vendor'), 
    filename: '[name].dll.js',
    library: '[name]_[hash]'
    // vendor.dll.js中暴露出的全局变量名。
    // 主要是给DllPlugin中的name使用,
    // 故这里需要和webpack.DllPlugin中的name,保持一致。
  },
  //在给定的 path 路径下创建一个名为 manifest.json 的文件。 这个文件包含了从 require 和 import 的request到模块 id 的映射。 DLLReferencePlugin 也会用到这个文件。
  plugins: [
    new webpack.DllPlugin({
      context: __dirname,
      // 定义打包的公共vendor文件对外暴露的函数名
      name: '[name]_[hash]',
      // manifest.json文件的输出位置
      path: path.join(__dirname, '..', 'dist/vendor/manifest.json')
    })
  ]
}
复制代码

webpack.dev.conf.js添加

devServer: {
    contentBase: resolve('dist'),  // 设置服务器从那个目录提供内容,默认当前 推荐使用绝对路径。
},
 plugins: [
    new HtmlWebpackPlugin({
      filename: resolve('/dist/index.html'), // 生成的html文件存放的地址和文件名
      template: resolve("/index.html"), // 基于index.html模板进行生成html文件
      vendor: './vendor/vendor.dll.js',
    }),
    new webpack.DllReferencePlugin({
      context: __dirname, // 跟dll.config里面DllPlugin的context一致
      manifest: require(path.join(__dirname, '..', 'dist', '/vendor/manifest.json')),
    }),
  ],
复制代码

在配置dllplugin的时候,有几个坑务必要注意!!!

  • webpack.dll.config.js中,output的library和new webpack.DllPlugin的name务必保持一致!
  • webpack.dev.conf.js中new webpack.DllReferencePlugin的执行上下文context必须和webpack.dll.config.js中的context保持一致!
  • devserver中必须设置contentBase静态文件指向!这里我们把打包出来的vendor.dll.js文件放在了dist文件夹下面。
  • 需要在index.html文件中引入vendor.dll.js文件,利用html-webpack-plugin获取设置的vendor属性
<script src="<%= htmlWebpackPlugin.options.vendor %>"></script>
复制代码

我们在package.json的scripts中添加命令行:

"dev_dll": "webpack --config build/webpack.dll.config.js",
复制代码

执行dev_dll就可以在看到打包好的vendor.dll.js文件

npm run dev_dll
复制代码

我们再执行npm run dev,我们可以看到delegated ... from dll-reference的打包引用,就说明了dllplugin引用成功了

[./node_modules/_react-dom@16.6.3@react-dom/index.js] delegated ../node_modules/_react-dom@16.6.3@react-dom/index.js from dll-reference vendor_3b82321a4a4ec9fad65d 42 bytes {home} [built]
复制代码

随着项目的丰富,我们可以把更多的不改动的三方包放在vendor.dll.js中,预计可以给项目带来30—40%的速度提升!

写在最后,dllplugin追求的是开发调试的时候尽可能减少webpack编译的时间,官方不推荐放在production中使用,一方面是dllplugin会打包重复代码(比如在vue项目中elementui,dllplugin会重复打包vue),这个也许可以进行一些优化,但是生产环境我们追求不再是时间,而是文件体积和加载速度等,感兴趣的童鞋可以自己研究一下~

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值