博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
基于webpack4.X从零搭建React脚手架
阅读量:6198 次
发布时间:2019-06-21

本文共 7647 字,大约阅读时间需要 25 分钟。


项目初始化

$ npm init复制代码

安装webpack

  • 本次创建是基于webpack4
$ npm install --save-dev复制代码

新建webpack配置文件

  • 在根目录创建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        
从零开始搭建react工程
复制代码

当前项目目录树

|- /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(    

hello, world!

, 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.jsconst 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 标签
    
从零开始搭建react工程
复制代码
  • 重新编译查看 npm run build 浏览器打开查看目录 dist 下的 index.html

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

  • 生成的文件名添加Hash值,目的是解决缓存问题
  • 修改webpack.prod.conf.js,mode: 'production', 增加以下代码
// webpack.prod.conf.jsoutput: {    filename: "js/[name].[chunkhash:16].js",},复制代码
  • 生成前需要清理之前项目生成的文件,因为由于文件名的改变如果不删除会一直增加
  • 安装插件 clean-webpack-plugin
$ npm install --save-dev clean-webpack-plugin复制代码
  • 修改 webpack.prod.conf.js
// webpack.prod.conf.jsconst 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中插入
  • 图片和路径处理
$ 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         }      }]},复制代码

转载地址:http://afica.baihongyu.com/

你可能感兴趣的文章
git log的常见用法
查看>>
the user must supply a jdbc connection 错误解决方法
查看>>
ASP.NET Core 2.0中如何更改Http请求的maxAllowedContentLength最大值
查看>>
MySQL 5.7 mysqlpump 备份工具说明
查看>>
kvm虚拟化平台搭建
查看>>
ping telnet ssh netstat
查看>>
oracle数据库用户删除及表空间删除
查看>>
EasyUI Menu 菜单
查看>>
微信小程序 Echarts 异步数据更新
查看>>
https页面打不开
查看>>
C++ 保存Excel文件(带密码保护)
查看>>
关于浏览器和屏幕的坐标大全(经典中的经典)
查看>>
我的微软开源CMS-Orchard源码阅读之Orchard.Caching
查看>>
AD域内DNS服务器如何解析公网域名
查看>>
Microsoft Phone Data Manager Beta 下载
查看>>
30天敏捷生活(3):设计你的生活看板
查看>>
PIC单片机增强型开发板产生两路PWM
查看>>
Android开发之旅: Intents和Intent Filters(理论部分)
查看>>
Nhibernate HQL 大全
查看>>
<<字符串高级截取和统计>>一文的C#正则实现
查看>>