• 基础搭建 Webpack4+React (jsx + less)


    React项目的初始化、webpack的安装、如何使用jsx和less。

    一、初始 React 项目

      react项目的初始化比较简单,我用的就是react的脚手架。三种方式

      1、NPM

    npm init react-app my-app
    

      2、NPX

    npx create-react-app my-app

      3、Yarn

    yarn create react-app my-app
    

      my-app 是项目的名字,运行命令时会在当前目录下自动创建一个名字叫作 my-app 的项目文件夹。命令运行完毕,简单的React项目就初始化完成了。项目的初始的代码结构式这个样子的:

      进入项目文件,你可以通过 npm run start 来运行项目,会跳出一个React的欢迎页

    my-app
    ├── README.md
    ├── node_modules
    ├── package.json
    ├── .gitignore
    ├── public
    │   ├── favicon.ico
    │   ├── index.html
    │   └── manifest.json
    └── src
        ├── App.css
        ├── App.js
        ├── App.test.js
        ├── index.css
        ├── index.js
        ├── logo.svg
        └── serviceWorker.js

    二、Webpack安装程序

      Webpack

        WebPack可以看做是模块打包机:它会分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(less、jsx、Scss、TypeScript等),并将其打包为合适的格式以供浏览器使用。

      为什么要用 WebPack ?

        1、模块化

          在webpack看来一切都是模块!这就是它不可不说的优点,包括你的JavaScript代码,也包括CSS和fonts以及图片等等等,只有通过合适的loaders,它们都可以被当做模块被处理。

        2、预处理(Less,Sass,ES6,TypeScript……)

        3、主流框架脚手架支持(Vue,React,Angular)

        4、庞大的社区(资源丰富,降低学习成本)

      

      1、开始安装Webpack

        使用 webpack 首先你需要安装 webpack-dev-server 在本地环境中为捆绑的应用程序提供服务、webpack-cli 在配置文件中来配置你的Webpack 设置。

    npm install --save-dev webpack webpack-dev-server webpack-cli
    

      

      2、修改 package.json

         主要修改 package.json 中的启动项

           

    "scripts": {
      "start": "webpack-dev-server --config config/webpack.base.config.js --mode development",
      ...
    }
    

            

        脚本将 webpack-dev-server 与名为 webpack.base.config.js 一起使用。我在项目的根目录下创建了一个 config 文件夹,里面用来存放 webpack 的配置文件。The --mode development flag just adds default Webpack configurations which came with Webpack 4.

          

      

      3、编辑 webpack.base.config.js

    module.exports = {
        entry: './src/index.js',
        output: {
          path: __dirname + '/public',
          publicPath: '/',
          filename: 'bundle.js'
        },
        devServer: {
          contentBase: './public'
        }
    };

        文件说明:

          (1) 我们希望使用 “./src/index.js” 文件作为入口点。

          (2) 绑定的文件最后生成的js文件,叫做: bundle.js .

          (3)生成的位置在:“/public”

      

      4、修改一下public/index.html 和 src/index.js 中的内容

        因为我们初步使用 webpack 来启动我们的项目,所以像是 svg图片react的识别都还没有配置。所以先将这两个文件进行修改,这些修改不会影响到之后咱们的搭建。将两个文件修改成下面的样子。

        public/index.html

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <title>React App</title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <base href="/">
      </head>
      <body>
        <noscript>You need to enable JavaScript to run this app.</noscript>
        <div id="root"></div>
        <script src="./bundle.js"></script>
      </body>
    </html>
    

        src/index.js

    console.log('My Minimal React Webpack Babel Setup');

      5、npm start

        OK,我们已经使用 webpack 将项目的启动脚本配置好了。下面就是使用 npm start 来验证我们的启动命令是否成功。   

        

        项目启动成功,接下来访问地址 localhost:8080 来访问一下。

        

        其中我们在 src/index.js 里面 console.log 的信息已经显示在了浏览器里边,说明 index.js 已经通过 webpack 编译成了 bundle.js。

    三、配置 babel

      babel 是一个广泛的转码器可以将 ES6 代码转化为 ES5 代码。从而在现有的环境中执行。

      1、安装插件

        在项目根目录下指定下面命令,作用是使得 babel 正常执行:

    npm install --save-dev @babel/core @babel/preset-env
    

         为了将它连接到Webpack,还需要安装一个加载器:

    npm install --save-dev babel-loader
    

         还需要一个配置,来将 React 的 jsx 语法转化成 JavaScript:

    npm install --save-dev @babel/preset-react
    

      2、编辑 webpack.base.config.js 文件

        在 webpack.base.config.js 文件中添加代码:

        module: {
          rules: [
              {
                  test: /.(js|jsx)$/,
                  exclude: /node_modules/,
                  use: ['babel-loader', 'eslint-loader']
              },
              {
                  test: /.(css|less)$/,
                  use:["style-loader", "css-loader", "less-loader"]
              },
              {
                  test: /.svg$/,
                  use: ['file-loader']
              }
          ]
        },
        resolve: {
          extensions: ['*', '.js', '.jsx', '.css', '.less']
        }

       

        这些代码的作用是 是代码识别 js、jsx、css、less、svg图片文件的。

        这里要下载几个 loader 和 plugin:

    npm install --save-dev style-loader css-loader less less-loader eslint-loader file-loader extract-text-webpack-plugin@next

        在项目根目录下创建 .babelrc 文件

          .babelrc

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

      3、修改 src/index.js 文件

        webpack 已经认less和css文件了。现在我们修改一下index.js

    import React from 'react';
    import ReactDOM from 'react-dom';
    import './index.css';
    import App from './App';
    import * as serviceWorker from './serviceWorker';
    
    ReactDOM.render(<App />, document.getElementById('root'));
    
    // If you want your app to work offline and load faster, you can change
    // unregister() to register() below. Note this comes with some pitfalls.
    // Learn more about service workers: http://bit.ly/CRA-PWA
    serviceWorker.unregister();
    

      然后将 App.css 改名为 App.less, 内容不需要改,如下图:

      

      OK,现在执行命令 npm start,访问 localhost:8080 看一下结果.

      

      成功。

    四、使用 webpack 打包项目

      1、首先我在 config 文件夹中创建 path.js、webpack.opt.config.js、 webpack.prod.config.js 三个文件

        path.js

          path 的作用是 提供path路径的,自定义的path。

    var path = require('path');
    var fs = require('fs');
    
    // Make sure any symlinks in the project folder are resolved:
    // https://github.com/facebookincubator/create-react-app/issues/637
    var appDirectory = fs.realpathSync(process.cwd());
    function resolveApp(relativePath) {
      return path.resolve(appDirectory, relativePath);
    }
    
    // We support resolving modules according to `NODE_PATH`.
    // This lets you use absolute paths in imports inside large monorepos:
    // https://github.com/facebookincubator/create-react-app/issues/253.
    
    // It works similar to `NODE_PATH` in Node itself:
    // https://nodejs.org/api/modules.html#modules_loading_from_the_global_folders
    
    // We will export `nodePaths` as an array of absolute paths.
    // It will then be used by Webpack configs.
    // Jest doesn't need this because it already handles `NODE_PATH` out of the box.
    
    // Note that unlike in Node, only *relative* paths from `NODE_PATH` are honored.
    // Otherwise, we risk importing Node.js core modules into an app instead of Webpack shims.
    // https://github.com/facebookincubator/create-react-app/issues/1023#issuecomment-265344421
    
    var nodePaths = (process.env.NODE_PATH || '')
      .split(process.platform === 'win32' ? ';' : ':')
      .filter(Boolean)
      .filter(folder => !path.isAbsolute(folder))
      .map(resolveApp);
    
    // config after eject: we're in ./config/
    module.exports = {
      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'),
      appNodeModules: resolveApp('node_modules'),
      nodePaths: nodePaths
    };

        webpack.opt.config.js

          webpack.opt.config.js 是在打包时做 css代码 优化的

    var OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
    var UglifyJsPlugin = require('uglifyjs-webpack-plugin');
    
    module.exports = {
      optimization: {
        minimizer: [
          new UglifyJsPlugin({
            uglifyOptions: {
              mangle: {
                keep_fnames: true,
              },
            },
          })
        ],
      },
      plugins: [
        new OptimizeCssAssetsPlugin()
      ],
    }
    

        webpack.prod.config.js

          webpack.prod.config.js 用来将各个 config 文件融合到一起

    var webpack = require('webpack');
    var merge = require('webpack-merge');
    
    var baseConfig = require('./webpack.base.config');
    var optimizationConfig = require('./webpack.opt.config');
    
    const productionConfiguration = function (env) {
      const NODE_ENV = env.NODE_ENV ? env.NODE_ENV : 'development';
      return {
        plugins: [
          new webpack.DefinePlugin({ 'process.env.NODE_ENV': JSON.stringify(NODE_ENV) }),
        ]
      };
    }
    
    module.exports = merge.smart(baseConfig, optimizationConfig, productionConfiguration);  

        安装  uglifyjs-webpack-plugin 和 webpack-merge :

    npm install --save-dev uglifyjs-webpack-plugin
    
     npm install --save-dev webpack-merge

      

      2、在项目根目录下创建 server 文件夹

        server 的作用是,打包成功之后,项目启动一个server。可以通过访问 server 地址来直接访问项目build之后生成的包。

          server/index.js

    const express = require('express');
    const path = require('path');
    const http = require('http');
    
    const app = express();
    
    // Point static path to dist
    app.use(express.static(path.join(__dirname, '..', 'build')));
    
    const routes = require('./routes')
    app.use('/', routes);
    
    /** Get port from environment and store in Express. */
    const port = process.env.PORT || '3000';
    app.set('port', port);
    
    /** Create HTTP server. */
    const server = http.createServer(app);
    /** Listen on provided port, on all network interfaces. */
    server.listen(port, () => console.log(`Server Running on port ${port}`))
    

          routes/index.js

    const path = require('path');
    const router = require('express').Router();
    
    router
      .get('/*', (req, res, next) => {
        const routePath = path.join(__dirname + '..', '..', '..','build/' + 'index.html');
        res.sendFile(routePath);
      })
    module.exports = router;
    

        这里面要安装一个 express:  

    npm install --save-dev express  
    

     

        

      3、修改 webpack.base.config.js

        webpack.base.config.js 最终版

    const webpack = require('webpack');
    var HtmlWebpackPlugin = require('html-webpack-plugin');
    var ExtractTextPlugin = require('extract-text-webpack-plugin');
    var paths = require('./paths');
    
    module.exports = {
        entry: './src/index.js',
        output: {
          path: paths.appBuild,
          publicPath: '/',
          filename: 'bundle.js'
        },
        module: {
            rules: [
                {
                    test: /.(js|jsx)$/,
                    exclude: /node_modules/,
                    use: ['babel-loader', 'eslint-loader']
                },
                {
                    test: /.(css|less)$/,
                    use:["style-loader", "css-loader", "less-loader"]
                    // use: ExtractTextPlugin.extract({
                    //   fallback: "style-loader",
                    //   use: "css-loader!less-loader",
                    // })
                },
                {
                    test: /.svg$/,
                    use: ['file-loader']
                }
            ]
        },
        plugins: [
            new webpack.HotModuleReplacementPlugin(),
            new HtmlWebpackPlugin({ 
                template: './public/index.html', 
                filename: './index.html' 
            }),
            new ExtractTextPlugin('style.css')
        ],
        resolve: {
            extensions: ['*', '.js', '.jsx', '.css', '.less']
        },
        devServer: {
          contentBase: './public',
          hot: true
        }
      };
    

        标红的部分是两种 css 的 load 方式。

          直接使用 " use: [] " : 打包时,css会被打包到 bundle.js 里面。

          使用 " use: ExtractTextPlugin.extract() " : plugin 中的 new ExtractTextPlugin('style.css') 联用。打包时会将css文件分离开来进行打包,在 build 文件夹中生成一个 style.css 文件.

        安装 html-webpack-plugin:

    npm install --save-dev html-webpack-plugin 
    

      4、package.json

         script 中的 build 换成如下语句

    "prestart:prod": "webpack --mode production --config config/webpack.prod.config.js --env.NODE_ENV=production --progress",
        "start:prod": "node server",

        

      5测试

        OK,全部配置完毕了,下面我们来测试一下是否成功。

          运行命令 npm run start:prod 

         

          build 生成的文件,三个如下:

                 

          运行成功,访问 localhost:3000 访问 build 好的包。

         

           

          执行命令: npm start

        

          

          访问 localhost:8080:

        

     

     

     

        

  • 相关阅读:
    Python
    Linux, Nginx
    Python
    C#图像处理(各种旋转、改变大小、柔化、锐化、雾化、底片、浮雕、黑白、滤镜效果)
    堆——神奇的优先队列(下)
    堆——神奇的优先队列(上)
    二叉树
    开启“树”之旅
    巧妙的邻接表(数组实现)
    Dijkstra最短路算法
  • 原文地址:https://www.cnblogs.com/Lyh1997/p/10372408.html
Copyright © 2020-2023  润新知