基礎搭建 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:

    

 

 

 

 

 

 

 

 

 

 

    

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM