从头搭建一个Webpack-React项目,基本配置

2,328 阅读3分钟

从头搭建一个Webpack-React项目,基本配置

参考链接: www.jianshu.com/p/0e01ca947…

1. 先初始化一个npm项目

npm init

可以根据自己的需求改一下,也可以直接一路next下去。
期望的结果:文件夹下面生成一个package.json

2. 添加webpack,并编写webpack.config.js

npm install webpack

我这里安装的是5.61.0版本,也可以

npm install webpack@5.61.0

在文件夹下面生成一个webpack.config.js

const path = require('path');
module.exports = {
  entry: './src/app.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'app.js'
  }
};
  • entry: 入口文件js的地址
  • output: 设置打包文件和打包文件夹
    • filename:打包文件
    • path:打包路径和文件夹名称

新建src/app.js

console.log('hello world')

3. 执行下方命令打包

node_modules/.bin/webpack

此时会让你安装webpack-cli来进行打包
期待结果:会生成一个dist文件夹,并将app.js打包在里面

4. 配置index.html

安装插件

npm install html-webpack-plugin

webpack.config.js配置

// 引入 用于配置index.html
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
  plugins: [
    new HtmlWebpackPlugin({
        template: './public/index.html' //* 配置index映射路径
    })
  ]
};
  • plugins:用于设置插件 使用上方打包语句
    期待结果: dist文件夹中出现index.html,并且app.js会被自动引入app.js

5. 解析es6脚本

安装编译器

npm install babel-loader@7.1.2 babel-core@6.26.0 babel-preset-env@1.6.1 --dev
module.exports = {
  rules: [//* 配置解析规则
    {
      test: /\.js$/,//* 配置解析的文件后缀名
      exclude: /(node_modules)/,  //* 不做处理的文件夹
      use: { //* 应用的解析模块,可以是一个数组,里面的值可以为模块名字符串,模块对象
        loader: 'babel-loader', //* 使用 babel-loader进行编译 */
        options: { //* 视具体来定,可以是一个字符串或者对象,值会传递到loader里面,为loader选项 */
          presets: ['env'] //* 选择使用的编译器
        }
      }
    }
  ]
}
  • rules: 配置解析规则
    • test: 配置解析的文件后缀名
    • exclude: 排除编译的文件夹 不做处理的文件夹
    • use: 应用的解析模块,可以是一个数组,里面的值可以为模块名字符串,模块对象
    • loader: 使用的编译器名称
    • options: 视具体来定,可以是一个字符串或者对象,值会传递到loader里面,为loader选项

6. 解析React

安装

npm install babel-preset-react
npm install react react-dom

配置jsx的解析器

rules: [
  {
    test: /\.jsx$/,
    exclude: /(node_modules)/,  //对这个不做处理
    use: {
      loader: 'babel-loader',
      options: {
        presets: ['env','react']    //在react环境下,也可以进行打包
      }
    }
  }
]

此时,需要三个步骤 \

  1. 将入口文件改为main.js,之前的app.js当成根组件使用,类似于Vue
  2. 在main.js中渲染app.js
  3. 在index.html中增加承载react的容器

将入口文件改为main.js,之前的app.js当成根组件使用,类似于Vue

  • webpack.config.js
entry: './src/main.js', //* 配置入口文件

app.jsx

const App = () => {
    return (<div>hello world</div>)
}

export default App

在main.js中渲染app.js

  • main.js
import React from 'react'
import ReactDom from './react-dom'

import App from './app'

ReactDom.render(<App />, document.getElementById('root')) //* 解析App到页面的root上

在index.html中增加承载react的容器

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

7. 解析css

安装

npm install style-loader css-loader

webpack.config.js rules

{
  test: /\.css$/,
  use: [ 'style-loader', 'css-loader' ]
}

如果只是配置css,到这一步即可。但是react的css会被编译成js,所以还需要用到ExtractTextWebpackPlugin todo 测试

npm install extract-text-webpack-plugin

webpack.config.js

const ExtractTextWebpackPlugin = require('extract-text-webpack-plugin')  //* 解析css为js
// rules 覆盖一下
{
  test: /\.css$/,
  use: ExtractTextWebpackPlugin.extract({
    fallback: "style-loader",
    use: "css-loader"
  })
}

8. 解析scss

安装:

npm install sass-loader@6.0.6 node-sass@4.7.2 --dev

如果报错python错误Error: Can't find Python executable "python", you can set the PYTHON env variable.

  • 电脑需要安装python2.7 www.python.org/downloads/r…
    查找下方windows x86-64 MSI installer版本并安装 一路next即可
  • 配置python环境变量 D:\data\env\python2.7
    D:\data\env\python2.7\Scripts
// cmd 管理员命令行中运行
npm install gulp-load-plugins --save
npm install --global --production windows-build-tools

如果还是不行则使用cnpm进行安装

npm install -g cnpm --registry=https://registry.npm.taobao.org
cnpm install node-sass --save

如果还是不行直接在package.json中指定版本

"sass-loader": "^7.1.0",
"node-sass": "^4.14.1"

再重新install一次

  • webpack.config.js rules
{
  test: /\.scss$/,
  use: ExtractTextWebpackPlugin.extract({
    fallback: 'style-loader',
    use: ['css-loader', 'sass-loader']
  })
}

9. 处理图片

安装

npm install file-loader@1.1.6 url-loader@0.6.2 --dev

webpack.confis.js rules

{
  test: /\.(png|jpg|gif)$/,
  use: [
    {
      loader: 'url-loader',
      options: {
        limit: 8192
      }
    }
  ]
}

10. 引入字体图标

安装

npm install font-awesome

webpack.config.js rules

{
  test: /\.(woff|woff2|eot|ttf|otf|svg)$/,
  use: [
    {
      loader: 'url-loader',
      options: {
        limit: 8192
      }
    }
  ]
}

11. 提取公共模块

webpack.config.js -> plugins todo 待测试

const webpack = require('webpack')
new webpack.optimize.CommonsChunkPlugin({ //* 提取公共模块
  name: "common", // 公共模块名
  filename: "js/base.js", // 打包的目录
}),

12. 安装webpack-dev-server 用于运行

npm install webpack-dev-server

配置webpack.config.js -> devServer

devServer: {
    port: 8788 //运行的端口
}

添加publicPath

output: {
  //* 用于配置打包后的信息
  path: path.resolve(__dirname, "dist"), //* 打包后的路径
  filename: "app.js", //* 打包后的入口文件
  publicPath: '/dist/'
},
webpack-dev-server 配置

命令行配置: 配置可以在命令行后面或者devServer中直接更改 \

  • –watch:动态监听文件的改变并实时打包
  • –hot: 热加载
  • -open: 编译完成后是否自动打开浏览器
  • --config:选择编译使用的webpack.config.js文件
使用并启动

webpack.config.js配置

entry: "./src/main.js", //* 配置入口文件
output: {
  //* 用于配置打包后的信息
  path: path.resolve(__dirname, "dist"), //* 打包后的路径
  filename: "app.js", //* 打包后的入口文件
  publicPath: '/dist/'
},

index.html设置

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Webpack-React</title>
    <!-- 引入app.js,必须得引入 不然不会显示 -->
</head>
<body>
    <div id="root"></div>
    <script src="dist/app.js"></script>
</body>
</html>

使用publicPath则script的引入路径为dist/app.js,如果不加则为app.js \

[React Error]: Target container is not a DOM element 使用publicPath如果出现这个问题的话,注意script的引入是不是在head中。因为引入script的时候dom还没更新,所以报找不到dom的问题

写hook组件时报错React is not defined

在main.js中将react注册到windows中

import React from 'react'
window.React = React

//todo

  1. 设置public文件夹
  2. @路径设置
  3. splitChunks代码切割
  4. 多环境 webpack.confis.js配置 示例:
    启动命令增加配置文件
{
  "scripts": {
     "start": "webpack-dev-server --open --config webpack.dev.js",
     "build": "webpack --config webpack.prod.js"
  }
}

webpack.common.js 通用配置 随各人编写
webpack.dev.js

const merge = require('webpack-merge');
const common = require('./webpack.common.js');

module.exports = merge(common, {
    mode: 'development',
    devtool: 'inline-source-map',
    devServer: {
        contentBase: './dist',
        port: 4001,
        hot: true
    }
});

最终

const path = require("path");
// 引入 用于配置index.html
const HtmlWebpackPlugin = require("html-webpack-plugin"); //* 解析index.html
const ExtractTextWebpackPlugin = require("extract-text-webpack-plugin"); //* 解析css为js
module.exports = {
  entry: "./src/main.js", //* 配置入口文件
  mode: 'development', // 设置mode环境
  output: {
    //* 用于配置打包后的信息
    path: path.resolve(__dirname, "dist"), //* 打包后的路径
    filename: "app.js", //* 打包后的入口文件
    publicPath: '/dist/'
  },
  devServer: {
    open: false,//* 编译好后是否自动打开浏览器
    port: 8788 //运行的端口
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: "./public/index.html", //* 配置index映射路径
      filename: 'index.html'//* 指定生成文件名称
    })
  ],
  module: {
    rules: [
      //* 配置解析规则
      {
        test: /\.js$/, //* 配置解析的文件后缀名
        exclude: /(node_modules)/, //* 不做处理的文件夹
        use: {
          //* 应用的解析模块,可以是一个数组,里面的值可以为模块名字符串,模块对象
          loader: "babel-loader", //* 使用 babel-loader进行编译 */
          options: {
            //* 视具体来定,可以是一个字符串或者对象,值会传递到loader里面,为loader选项 */
            presets: ["env", "react"], //* 环境
          },
        },
      },
      {
        test: /\.jsx$/,
        exclude: /(node_modules)/, //对这个不做处理
        use: {
          loader: "babel-loader",
          options: {
            presets: ["env", "react"], //在react环境下,也可以进行打包
          },
        },
      },
      {
        test: /\.css$/,
        use: ExtractTextWebpackPlugin.extract({
          fallback: "style-loader",
          use: "css-loader",
        }),
      },
      {
        test: /\.scss$/,
        use: ExtractTextWebpackPlugin.extract({
          fallback: "style-loader",
          use: ["css-loader", "sass-loader"],
        }),
      },
      {
        test: /\.(png|jpg|gif)$/,
        use: [
          {
            loader: "url-loader",
            options: {
              limit: 8192,
            },
          },
        ],
      },
      {
        test: /\.(woff|woff2|eot|ttf|otf|svg)$/,
        use: [
          {
            loader: "url-loader",
            options: {
              limit: 8192,
            },
          },
        ],
      },
    ],
  },
};

package.json

{
  "name": "webpack-react",
  "version": "1.0.0",
  "description": "从头搭建的webpack-react项目",
  "main": "main.js",
  "scripts": {
    "dev": "node_modules/.bin/webpack-dev-server --mode development",
    "webpack-dev": "node_modules/.bin/webpack --mode development",
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "node_modules/.bin/webpack"
  },
  "author": "q",
  "license": "ISC",
  "dependencies": {
    "babel-core": "^6.26.0",
    "babel-loader": "^7.1.2",
    "babel-preset-env": "^1.6.1",
    "babel-preset-react": "^6.24.1",
    "css-loader": "^6.5.1",
    "extract-text-webpack-plugin": "^3.0.2",
    "file-loader": "^1.1.6",
    "font-awesome": "^4.7.0",
    "gulp-load-plugins": "^2.0.7",
    "html-webpack-plugin": "^5.5.0",
    "node-sass": "^4.14.1",
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "sass-loader": "^7.1.0",
    "style-loader": "^3.3.1",
    "url-loader": "^0.6.2",
    "webpack": "^5.61.0",
    "webpack-dev-server": "^4.4.0"
  },
  "devDependencies": {
    "webpack-cli": "^4.9.1"
  }
}