基于webpack4.X从零搭建React脚手架

栏目: JavaScript · 发布时间: 7年前

  • 在根目录创建build文件夹,添加一个js文件,命名为webpack.base.conf.js
// webpack.base.conf.js 文件
const path = require('path');
const DIST_PATH = path.resolve(__dirname, '../dist');
module.exports = {
        entry: {
            app: './app/index.js'
        },
        output: {
            filename: "js/bundle.js",
            path: DIST_PATH
        }
};
复制代码

使用merge的方式来组织webpack基础配置和不同环境的配置

  • 先安装webpack-merge:
$ npm install --save-dev webpack-merge
复制代码
  • 在build文件夹中再添加一个js文件,命名为 webpack.prod.conf.js
// webpack.prod.conf.js 文件
const merge = require('webpack-merge');
const baseWebpackConfig = require('./webpack.base.conf');
module.exports = merge(baseWebpackConfig, {
    mode: 'production'
});
复制代码

在根目录下创建app目录,然后创建index.js文件

var element =document.getElementById('root');
element.innerHTML = 'hello, world!';
复制代码
  • 在根目录创建一个public文件夹,然后新建一个index.html文件
// index.html
<!DOCTYPE html>
<html lang="en">
  <head>
      <meta charset="UTF-8">
      <title>从零开始搭建react工程</title>
  </head>
  <body>
        <div id="root"></div>
        <script src="../dist/js/bundle.js"></script>
  </body>
</html>
复制代码

当前项目目录树

|- /app
    |- index.js
  |- /node_modules
  |- /public
    |- index.html
  |- /build
    |- webpack.base.conf.js
    |- webpack.prod.conf.js
  |- package.json
  |- package-lock.json
复制代码

安装webpack-cli

  • webpack 4.0 版本之后的webpack,已经将webpack命令 工具 迁移到webpack-cli模块了,需要安装 webpack-cli
$ npm install --save-dev webpack-cli
复制代码

package.json文件 scripts属性配置一个build命令

  • 其值为:webpack --config build/webpack.prod.conf.js,以下是scripts的相关代码
// package.json
"scripts": {
    "build": "webpack --config build/webpack.prod.conf.js",
    "test": "echo \"Error: no test specified\" && exit 1"
},
复制代码

安装React

$ npm install --save react react-dom
复制代码
  • 修改app目录下的index.js的代码
import React from "react";
import ReactDom from "react-dom";

ReactDom.render(
    <h1>hello, world!</h1>,
    document.getElementById("root")
);
复制代码
  • 注意 import 属于ES6规范,因此需要转译ES2015+的语法,安装并配置 babel 以及相关依赖
$ npm install --save-dev babel-loader babel-core babel-preset-env babel-preset-react
复制代码
  • 根目录创建.babelrc文件,配置presets.
{
  "presets": [
    [
      "env",
      {
        "targets": {
          "browsers": [
            "> 1%",
            "last 5 versions",
            "ie >= 8"
          ]
        }
      }
    ],
    "react"
  ]
}
复制代码
  • 修改webpack.base.conf.js文件
// webpack.base.conf.js
const path = require('path');
const APP_PATH = path.resolve(__dirname, '../app');
const DIST_PATH = path.resolve(__dirname, '../dist');
module.exports = {
    entry: {
        app: './app/index.js'
    },    
    output: {
        filename: 'js/bundle.js',
        path: DIST_PATH
    },
    module: {
        rules: [
            {
                test: /\.js?$/,
                use: "babel-loader",
                include: APP_PATH
            }
        ]
    }
};
复制代码
  • 运行 npm run build

添加插件

  • public下的index.html本该自动添加到dist目录,并且引用资源自动加载到该文件,通过html-webpack-plugin实现这一步
$ npm install html-webpack-plugin --save-dev
复制代码
  • webpack.prod.conf.js中配置plugins属性
const merge = require('webpack-merge');
const baseWebpackConfig = require('./webpack.base.conf.js');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = merge(baseWebpackConfig, {
    mode: 'production',
    plugins: [
        new HtmlWebpackPlugin({
            template: 'public/index.html',
            inject: 'body',
            minify: {
                removeComments: true,
                collapseWhitespace: true,
                removeAttributeQuotes: true
            },
        })
    ]
});
复制代码
  • 删除 index.html 中手动引入的 script 标签
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>从零开始搭建react工程</title>
</head>
<body>
    <div id="root"></div>
</body>
</html>
复制代码
  • 重新编译查看 npm run build 浏览器打开查看目录 dist 下的 index.html

以上步骤都成功的前提下继续走下一步

  • 生成的文件名添加Hash值,目的是解决缓存问题
  • 修改webpack.prod.conf.js,mode: 'production', 增加以下代码
// webpack.prod.conf.js
output: {
    filename: "js/[name].[chunkhash:16].js",
},
复制代码
  • 生成前需要清理之前项目生成的文件,因为由于文件名的改变如果不删除会一直增加
  • 安装插件 clean-webpack-plugin
$ npm install --save-dev clean-webpack-plugin
复制代码
  • 修改 webpack.prod.conf.js
// webpack.prod.conf.js
const merge = require('webpack-merge');
const baseWebpackConfig = require('./webpack.base.conf.js');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');

module.exports = merge(baseWebpackConfig, {
    mode: 'production',
    output: {
        filename: "js/[name].[chunkhash:16].js",
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: 'public/index.html',
            inject: 'body',
            minify: {
                removeComments: true,
                collapseWhitespace: true,
                removeAttributeQuotes: true
            },
        }),
        new CleanWebpackPlugin(['../dist'], { allowExternal: true })
    ]
});
复制代码

公共代码与业务代码分离

  • 修改 webpack.base.conf.js 的 entry 入口属性,抽出框架代码
entry: {
      app: './app/index.js',
      framework: ['react','react-dom'],
},
复制代码
  • 修改webpack.prod.conf.js,增加以下代码,目的是分离框架代码和业务代码
  • 虽然上面步骤抽出框架代码生成两个文件,但是app.js还是包含框架代码
optimization: {
        splitChunks: {
            chunks: "all",
            minChunks: 1,
            minSize: 0,
            cacheGroups: {
                framework: {
                    test: "framework",
                    name: "framework",
                    enforce: true
                }
            }
        }
    }
复制代码
  • cacheGroups对象,定义了需要被抽离的模块
  • 其中test属性是比较关键的一个值,他可以是一个字符串,也可以是正则表达式,还可以是函数。如果定义的是字符串,会匹配入口模块名称,会从其他模块中把包含这个模块的抽离出来
  • name是抽离后生成的名字,和入口文件模块名称相同,这样抽离出来的新生成的framework模块会覆盖被抽离的framework模块

整合 webpack-dev-server

  • 开发环境开启服务监听文件改动实时更新最新内容
$ npm install --save-dev webpack-dev-server
复制代码
  • 在build中添加webpack.dev.conf.js文件
const path = require('path');
const merge = require('webpack-merge');
const baseWebpackConfig = require('./webpack.base.conf.js');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack');

module.exports = merge(baseWebpackConfig, {
    mode: 'development',
    output: {
        filename: "js/[name].[hash:16].js",
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: 'public/index.html',
            inject: 'body',
            minify: {
                html5: true
            },
            hash: false
        }),
        new webpack.HotModuleReplacementPlugin()
    ],
    devServer: {
        port: '8080',
        contentBase: path.join(__dirname, '../public'),
        compress: true,
        historyApiFallback: true,
        hot: true,
        https: false,
        noInfo: true,
        open: true,
        proxy: {}
    }
});
复制代码
  • 在package.json scripts属性添加内容
"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
复制代码
  • npm run dev
  • 自动打开浏览器打开入口页面实时更新

独立导出 css 文件

  • 安装css相关依赖
  • sass less 预处理
$ npm install extract-text-webpack-plugin
$ npm install style-loader css-loader postcss-loader autoprefixer --save-dev
$ npm install less sass less-loader sass-loader stylus-loader node-sass --save-dev
复制代码
  • webpack.base.conf.js 文件修改
// webpack.base.conf.js
{
    test: /\.css$/,
    use: [
        {
          loader: "style-loader" //在html中插入<style>标签
         },
         {
             loader: "css-loader",//获取引用资源,如@import,url()
         },
         {
              loader: "postcss-loader",
              options: {
                    plugins:[
                       require('autoprefixer')({
                           browsers:['last 5 version']
                       })
                  ]
              }
        }
     ]
},
{
   test:/\.less$/,
   use: [
         {  loader: "style-loader"  },
         {  loader: "css-loader" },
         {
            loader: "postcss-loader",//自动加前缀
            options: {
                   plugins:[
                          require('autoprefixer')({
                              browsers:['last 5 version']
                          })
                  ]
            }
         },
         {  loader: "less-loader" }
     ]
},
{
      test:/\.scss$/,
      use:[
             {  loader: "style-loader"  },
             {
                      loader: "css-loader",
             },
             {  loader: "sass-loader" },
             {
               loader: "postcss-loader",
              options: {
                    plugins:[
                         require('autoprefixer')({
                           browsers:['last 5 version']
                         })
                   ]
              }
          }
     ]
},
复制代码
  • 图片和路径处理
$ npm i file-loader url-loader --save-dev
复制代码
  • webpack.base.conf.js 文件修改
// webpack.base.conf.js
{
    test: /\.(png|jpg|gif|woff|svg|eot|woff2|tff)$/,
    use: 'url-loader?limit=8129', 
    //注意后面那个limit的参数,当你图片大小小于这个限制的时候,会自动启用base64编码图片
    exclude: /node_modules/
}
复制代码

build 时报错

Error: Chunk.entrypoints: Use Chunks.groupsIterable and filter by instanceof Entrypoint instead
    at Chunk.get (F:\react\createApp\node_modules\webpack\lib\Chunk.js:824:9)
复制代码
  • webpack4.0中使用“extract-text-webpack-plugin”报错
  • 解决办法
$ npm install extract-text-webpack-plugin@next
复制代码

背景图片路径问题

  • 由于css文件分离出来的原因,会导致在css文件夹下找images文件夹下的图片
  • 解决办法 publicPath属性改为 '/',以绝对路径的方式寻找资源
{
    test:/\.(png|jpg|gif)$/,
    use:[{
        loader:'url-loader',
        options: {
              // outputPath:'../',//输出**文件夹
              publicPath: '/',
              name: "images/[name].[ext]",
              limit:500  //是把小于500B的文件打成Base64的格式,写入JS
         }
      }]
},
复制代码

以上所述就是小编给大家介绍的《基于webpack4.X从零搭建React脚手架》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

The Art and Science of CSS

The Art and Science of CSS

Jonathan Snooks、Steve Smith、Jina Bolton、Cameron Adams、David Johnson / SitePoint / March 9, 2007 / $39.95

Want to take your CSS designs to the next level? will show you how to create dozens of CSS-based Website components. You'll discover how to: # Format calendars, menus and table of contents usin......一起来看看 《The Art and Science of CSS》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具