webpack从零开始搭建react开发脚手架

2 篇文章 0 订阅

webpack从零开始搭建react开发脚手架

  • style-loader

    可以给每一个模块加入一个标志。

  • less-loader
    将less所写得样式代码转换为css代码,

  • css-loader
    解析@import()和less或者css里面的url()

  • url-loader
    将引入的文件转换为base64位,

  • html-webpack-plugin
    能自动生成一个html文件并把我们打包好的js文件放入html

  • @babel/core babel-loader@8 @babel/preset-env @babel/preset-react

    这几个插件可以让babel去解析jsx文件

  • webpack-dev-server
    提供了对Webpack资产的快速内存访问,可提供一个热更新的开发dev环境

建立好的文件目录

在这里插入图片描述

build环境搭建

最简单的webpack build配置

  1. 创建空的文件夹命名为test-app

  2. 生成package.json,并安装webpack

    npm init
    npm install webpack webpack-cli --save-dev
    
  3. 在根目录下创建webpack.config.js,填入

    const path=require("path");
    module.exports={
        entry:'./index.js',//指定入口文件
        mode:'production',// 指定打包模式
        output:{
            filename:'build.js',// 打包过后的名字
            path:path.resolve(__dirname,'build')//打包的位置
        }
    }
    
  4. 在package.json的scripts模块中填入build,打开控制台执行npm run build,可以在根目录下发现自动创建勒一个文件夹为build,文件里出现build,即是webpack.config.js中写好的配置。

    {
      "name": "test-app",
      "version": "1.0.0",
      "description": "",
      "main": "index.js",
      "scripts": {
        "build":"webpack index.js",
        "test": "echo \"Error: no test specified\" && exit 1"
      },
      "author": "",
      "license": "ISC",
      "devDependencies": {
        "webpack": "^4.41.0",
        "webpack-cli": "^3.3.9"
      }
    }
    
    

ps:npm run 原理及后面的脚本为什么能够执行?

npm run 会自动新建一个 Shell,在这个 Shell 里面执行指定的脚本命令,package.json中的scripts字段一个键值对对应一条shell命令,在我们的这个地方。npm run build 等于webpack index.js,前面安装的webpack和webpack-cli是前提,在npm run 的时候会去node_modules下的bin目录下查找相应的执行命令。

完全build环境搭建

  1. 在config文件夹内新建paths.js写入

    const path=require('path');
    const fs=require('fs');
    const appDir=fs.realpathSync(process.cwd());
    const resolveApp=(realPath)=>path.resolve(appDir,realPath);
    module.exports={
       dotenv: resolveApp('.env'),
      appBuild: resolveApp('build'),
      appPublic: resolveApp('public'),
      appHtml: resolveApp('public/index.html'),
      appIndexJs: resolveApp('src/index.js'),
      appPackageJson: resolveApp('package.json'),
      appSrc: resolveApp('src'),
      yarnLockFile: resolveApp('yarn.lock'),
      testsSetup: resolveApp('src/setupTests.js'),
      appNodeModules: resolveApp('node_modules'),
    }
    

    这里我们需要使用node的fs模块,需要在webpack.config.js中写入

    "target":"node""node":{fs:"empty"}//实际使用这个方式,上面那个方式打包出来之后会报错
    
  2. 将webpack.config.js移动到config目录下并改名为webpack.config.prod.js,

  3. 在scripts目录下新建build.js并写入

    const webpack=require('webpack');
    
    const config=require("../config/webpack.config.prod");
    
    build();
    
    function build(){
    
        console.log("开始build项目")
    
        let compier=webpack(config);
    
        compier.run((err,stats)=>{
    
            console.log(err);
    
        })
    
    }
    
  4. 往webpack.config.prod.js中写入less,和html-webpack-plugin,执行安装npm install html-webpack-plugin --save-dev,新的webpack.config.prod.js如下,html-webpack-plugin, 需要模板,在public下建立index.html,并在配置文件中的插件配置出指定模板为该目录下的index.html,index.html只需要在body中设立一个id为root的div即可

    const path = require('path');
    const HtmlWebpackPlugin = require('html-webpack-plugin');
    const paths=require('./paths.js')
    module.exports = {
     entry: paths.appIndexJs,
     mode: "production",
     output: {
       path: paths.appBuild,
       filename: 'app.js'
     },
    node: { fs: "empty" },
     module: {
       rules: [
         {
           test: /\.(css|less)$/,
           use: [ 'style-loader',
            'css-loader' ,
           { loader: 'less-loader', options: { strictMath: true, noIeCompat: true } }],
         },
           {
           test: /\.(png|svg|jpg|gif)$/,
           use: ['url-loader'],
           include:paths.appSrc,
         },
         {
           test: /\.(woff|woff2|eot|ttf|otf)$/,
           use: ['url-loader'],
              include:paths.appSrc,
         }
       ],
     },
     plugins: [
       new HtmlWebpackPlugin({
         inject: true,
         template: paths.appHtml,
         minify: {
           removeComments: true,
           collapseWhitespace: true,
           removeRedundantAttributes: true,
           useShortDoctype: true,
           removeEmptyAttributes: true,
           removeStyleLinkTypeAttributes: true,
           keepClosingSlash: true,
           minifyJS: true,
           minifyCSS: true,
       	minifyURLs: true,
         },
       }),
     ]
    };
    
  5. 解析jsx文件配置

    需要安装babel解析jsx文件,**注意:**按照我这里的安装方式可以实现解析jsx,安装其他的不可行,具体配置可以查看babel官方文档

    npm install @babel/core babel-loader@8 @babel/preset-env @babel/preset-react --save-dev
    

    配置babel有两种方式,一种是在package.json中填入,一种是在根目录新建.babelrc填入,

    {
      "presets": [
          "@babel/preset-react","@babel/preset-env",
    ]
    }
    

    在webpack.config.prod.js 中的rules中写入

    {
    				test: /\.(js|jsx)$/,
         			exclude: paths.appNodeModules,
    				use: {
           				loader: 'babel-loader',
    				}
    			},
    
  6. src目录下新建index.js,写入react的入口

    
    import React from 'react';
    import ReactDom from 'react-dom';
    import './styles/index.less'
    
    ReactDom.render(
    	(<h1>hello orldasdasdasdassdaasdad</h1>),
    	document.getElementById('root')
    );
    
  7. 最后一步,修改package.json文件中的scripts中的build,为

    "build": "node scripts/build.js",
    

    这样既可以build出来一个可部署的项目了。build环境搭建完成。

dev开发环境搭建

  1. pageage.json中的scripts添加脚本
"start": "node scripts/start.js",
  1. 相应目录下建立start.js,控制台执行npm install webpack-dev-server react-dev-utils --save-dev

    start.js内容如下

    const webpack=require('webpack');
    const config=require("../config/webpack.config.dev");
    const {
        choosePort,
        createCompiler,
        prepareProxy,
        prepareUrls,
    } = require('react-dev-utils/WebpackDevServerUtils');
    const HOST = process.env.HOST || '0.0.0.0';
    const paths=require("../config/paths");
    const clearConsole = require('react-dev-utils/clearConsole');
    const WebpackDevServer=require("webpack-dev-server");
    const createDevServerConfig=require("../config/devService.config");
    const isInteractive = process.stdout.isTTY;
    const DEFAULT_PORT=3330;
    choosePort(HOST,DEFAULT_PORT).then(port=>{
          const protocol = process.env.HTTPS === 'true' ? 'https' : 'http';
        const appName = require(paths.appPackageJson).name;
        const urls = prepareUrls(protocol, HOST, port);
        const compiler=createCompiler({webpack, config, appName, urls});
        const proxySetting = require(paths.appPackageJson).proxy;
         const proxyConfig = prepareProxy(proxySetting, paths.appPublic);
         const serverConfig = createDevServerConfig(
          proxyConfig,
          urls.lanUrlForConfig
        );
        console.log("proxyConfig",serverConfig)
        const devServer = new WebpackDevServer(compiler, serverConfig);
         // Launch WebpackDevServer.
        devServer.listen(port, HOST, err => {
          if (err) {
            return console.log(err);
          }
          if (isInteractive) {
            clearConsole();
          }
          console.log('启动dev服务');
        });
     ['SIGINT', 'SIGTERM'].forEach(function(sig) {
          process.on(sig, function() {
            devServer.close();
            process.exit();
          });
        });
    })
    
  2. 在当前目录下复制webpack.config.prod.js并改名为webpack.config.dev.js并更改mode为development

  3. 在config文件下新建devService.config.js,填入以下内容

    const config = require('./webpack.config.dev');
    const paths = require('./paths');
    const protocol = process.env.HTTPS === 'true' ? 'https' : 'http';
    const host = process.env.HOST || '0.0.0.0';
    
    module.exports = function(proxy, allowedHost) {
      return {
        disableHostCheck:
          !proxy || process.env.DANGEROUSLY_DISABLE_HOST_CHECK === 'true',
        compress: true,
        clientLogLevel: 'none',
        contentBase: paths.appPublic,
        watchContentBase: true,
        hot: true,
        publicPath: config.output.publicPath,
        quiet: true,
        https: protocol === 'https',
        host: host,
        overlay: false,
        historyApiFallback: {
          disableDotRule: true,
        },
        public: allowedHost,
        proxy,
      };
    };
    

    dev环境搭建完毕。

    后言

    此处搭建的脚手架完成了打包部署的任务和开发时热更新的任务,还有其他打包优化和性能提升方面的配置还没有加入,如果错误之处还望指正。搭建的这个脚手架地址是:https://gitee.com/cgsx/create-app-text。

    搭建这个脚手架的过程中,收获还是挺多的,踩了一些坑,知道了一些插件的使用,以及如何利用不同的插件来完成一些自动化工程的事情,具体的插件源码没有研读。只是浅显的知道这个插件的用途,收获还是满满的

    public: allowedHost,
    proxy,
    

    };
    };

    
    dev环境搭建完毕。
    
    ## 后言
    
    此处搭建的脚手架完成了打包部署的任务和开发时热更新的任务,还有其他打包优化和性能提升方面的配置还没有加入,如果错误之处还望指正。搭建的这个脚手架地址是:https://gitee.com/cgsx/create-app-text。
    
    搭建这个脚手架的过程中,收获还是挺多的,踩了一些坑,知道了一些插件的使用,以及如何利用不同的插件来完成一些自动化工程的事情,具体的插件源码没有研读。只是浅显的知道这个插件的用途,收获还是满满的
    
    
    
    
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值