目次
react-sample-javascript
プロジェクトの初期化
統一された標準化されたコード形式
预期功能
目录结构
安装依赖
项目配置
webpack 基础配置
entry
output
出力
resolve
module
Webpack开发配置
项目进阶
生产环境配置
代码分离
css代码压缩
生成HTML
复制静态目录
开启打包分析
ssh部署
ホームページ ウェブフロントエンド jsチュートリアル webpack4 に基づいて反応スキャフォールディングを構築する方法のプロセス分析

webpack4 に基づいて反応スキャフォールディングを構築する方法のプロセス分析

Jul 26, 2018 am 11:59 AM

この記事で共有する内容は、webpack4 に基づいて反応スキャフォールディングを構築する方法のプロセス分析です。次に、困っている友人を助けることを願って、具体的な内容を見てみましょう。

react-sample-javascript

react-router-dom、redux、webpack 4を使用したReact 16.0ボイラープレート(JavaScript用)
githubプロジェクトアドレス

プロジェクトの初期化

統一された標準化されたコード形式

  1. 設定 .editorconfig により IDE が統一されます (コードを参照).editorconfig 使得IDE的方式统一 (见代码)

  2. 配置 .eslintrc.js 使得代码规范统一 (见代码)

    预期功能

  3. 管理资源: 能加载css、sccc、less、以及静态文件

  4. 管理输出:将打包后的静态文件输出至static目录下,以各自的文件类型管理

  5. dev:使用source map,方便调试时代码定位

  6. dev:配置devServer,并配置热替换,热加载,自动刷新,自动打开浏览器,并预留proxyTable

  7. dev:设置默认打开8080,被占用则寻找下一个空接口

  8. production:代码分离,打包css文件,css代码压缩,js代码压缩,输出到模板html,配置gzip

  9. analysis::使用BundleAnalyzerPlugin 分析打包后的性能

    目录结构

  • 首先使用npm init 初始化一个包含package.json的根目录

:.
│  .babelrc             #babel的规则以及插件
│  .editorconfig        #IDE/编辑器相关的配置
│  .eslintignore        #Eslint忽视的目录
│  .eslintrc.js         #Eslint的规则和插件
│  .gitignore           #Git忽视的目录
│  .postcssrc.js        #postcss的插件
│  package-lock.json
│  package.json         #项目相关的包
│  README.md
│  yarn.lock
│
├─build                 #webpack相关的配置
│      utils.js         #webpack配置中的通用方法
│      webpack.base.conf.js #webpack的基础配置
│      webpack.dev.conf.js  #webpack的开发环境配置
│      webpack.prod.conf.js #webpack的生产环境配置
│
└─src                   #主目录,业务代码
    │  app.css
    │  App.js
    │  favicon.ico
    │  index.ejs
    │  index.js
    │
    └─assets            #静态目录,存放静态资源
        │  config.json
        │
        └─img
                logo.svg
ログイン後にコピー

安装依赖

  • eslint-loader

  • eslint

  • eslint-config-airbnb

  • eslint-plugin-import

  • eslint-friendly-formatter

  • eslint-plugin-flowtype

  • eslint-plugin-jsx-a11y

  • eslint-plugin-react

  • babel-polyfill

  • webpack

  • jest

  • friendly-errors-webpack-plugin 编译提示的webpack插件

  • html-webpack-plugin 新建html入口文件的webpack插件

  • copy-webpack-plugin webpack配置合并模块

  • webpack-merge webpack配置合并模块

  • webpack-dev-server

  • webpack-bundle-analyzer

  • webpack-cli

  • portfinder 寻找接口的插件

  • extract-text-webpack-plugin

  • node-notifier

  • optimize-css-assets-webpack-plugin

  • autoprefixer

  • mini-css-extract-plugin

  • autoprefixer

  • css-loader

  • less-loader

  • postcss-loader

  • postcss-import

  • postcss-loader

  • style-loader

  • babel-core

  • babel-eslint

  • babel-loader

  • babel-plugin-transform-runtime

  • babel-plugin-import

  • babel-preset-env

  • babel-preset-react

  • babel-polyfill

  • url-loader

  • cross-env

  • file-loader

yarn add eslint eslint-loader eslint-config-airbnb eslint-plugin-import eslint-friendly-formatter eslint-plugin-flowtype eslint-plugin-jsx-a11y eslint-plugin-react babel-polyfill webpack jest webpack-merge copy-webpack-plugin html-webpack-plugin friendly-errors-webpack-plugin webpack-dev-server webpack-bundle-analyzer webpack-cli portfinder extract-text-webpack-plugin node-notifier optimize-css-assets-webpack-plugin autoprefixer mini-css-extract-plugin autoprefixer css-loader less-loader postcss-loader postcss-import postcss-loader style-loader babel-core babel-eslint babel-loader babel-plugin-transform-runtime babel-plugin-import babel-preset-env babel-preset-react babel-polyfill url-loader cross-env file-loader -D
ログイン後にコピー

项目配置

webpack 基础配置

  1. 为了控制开发环境和生产环境,我们可以新建build文件夹。分别书写开发环境和生产环境的webpack配置文件,这样也更可以方便我们分别控制生产环境和开发环境。

  2. 为了提高代码的复用率,也为了区别 基础配置个性配置 ,可以分别新建webpack.basewebpack.devwebpack.prod三个配置文件。首先配置最基础的entry(入口)和output(出口)。

module.exports = {
  context: path.resolve(__dirname, '../'),  //绝对路径。__dirname为当前目录。
    //基础目录用于从配置中解析入口起点。因为webpack配置在build下,所以传入 '../'
  entry: {
    app: ('./src/index.js') //项目的入口
  },
  output: {
    path: path.resolve(__dirname, '../dist'),
    filename: '[name].[hash:8].js',
    publicPath: '/',
    libraryTarget: 'umd',
  },
}
ログイン後にコピー

entry

entry可以分别为字符串、数组和对象。

倘若应用只有一个单一的入口,entry的值可以使用任意类型,不会影响输出结果。

// entry为字符串
{
    entry: './src/index.js',
    output: {
        path: '/dist',
        filename: 'bundle.js'
    }
}
// 结果会生成 '/dist/bundle.js'
ログイン後にコピー
// entry为数组,可以添加多个彼此不互相依赖的文件。结合output.library选项,如果传入数组,则只导出最后一项。
{
    //如果你在html文件里引入了'bable-polyfill',可以通过数组将它加到bundle.js的最后。
    entry: ['./src/index.js', 'babel-polyfill'] ,
    output:{
        path: '/dist',
        filename: 'bundle.js'
    }
}
ログイン後にコピー
// entry为对象,可以将页面配置为多页面的而不是SPA,有多个html文件。通过对象告诉webpack为每个入口,成一个bundle文件。
// 多页面的配置,可能还要借助于HtmlWebpackPlugin,来指定每个html需要引入的js
{
    entry: {
        index: './src/index.js'
        main: './src/index.js'
        login: './src/login.js'
    }
    output:{
        path: '/dist/pages'
        filename: '[name]-[hash:5].js' //文件名取自'entry'对象的键名,为了防止推送代码后浏览器读缓存,故再生成的文件之后加上hash码。
    }
}
// 会分别生成index.js,main.js,login.js三个文件
ログイン後にコピー

关于 webpack构建多页面 可以参考这篇文章。不过现在webpack4.x也是一次断崖式升级,感兴趣的同学可以自行搜索。

// entry也可以传入混合类型
{
    entry:{
        vendor: ['jquery','amap','babel-polyfill'] //也可以借助CommonsChunkPlugin提取vendor的chunk。
        index: './src/index.js'
    }
    output: {
        path: '/dist'
        filename: '[name]-[hash:5].js'
    }
}
ログイン後にコピー

CommonsChunkPlugin在webpack4.0之后移除了,可以使用splitChunksPlugin代替。

output

output最基础的两个配置为 pathfilename

  • path 告诉 webpack的输出目录在那里,一般我们会设置在根目录的 dist 文件夹;

  • filename 用于指定输出文件的文件名,如果配置了创建了多个单独的 chunk 则可以使用[name].[hash]

  • 🎜Configuration .eslintrc.js によりコード仕様が統一されます (コードを参照)🎜🎜期待される機能🎜< /li >🎜🎜リソースの管理: css、sccc、less、および静的ファイルをロードできます🎜🎜🎜出力の管理: パッケージ化された静的ファイルを静的ディレクトリに出力し、それぞれのファイルタイプに従って管理します🎜 🎜🎜dev: ソース マップを使用して、デバッグ中のコードの位置決めを容易にします🎜🎜🎜dev: devServer を構成し、ホット リプレースメント、ホット ロード、自動リフレッシュを構成し、ブラウザーを自動的に開き、proxyTable を予約します🎜 > 🎜🎜dev: デフォルトで 8080 を開くように設定します。占有されている場合は、次の空のインターフェイスを探します🎜🎜🎜制作: コード分離、CSS ファイルのパッケージ化、CSS コード圧縮、JS コード圧縮、テンプレート HTML への出力、 gzip を設定します🎜< /li>🎜🎜分析:: BundleAnalyzerPlugin を使用してパッケージングのパフォーマンスを分析します🎜🎜ディレクトリ構造🎜
      🎜🎜最初に npm を使用しますinit を使用して、.json のルート ディレクトリを含むパッケージを初期化します🎜
     output: {
        path: path.resolve(__dirname, &#39;../dist&#39;),
        filename: &#39;[name].[hash:8].js&#39;,
        publicPath: &#39;/&#39;,
      },
    ログイン後にコピー
    ログイン後にコピー
    🎜インストールの依存関係🎜
      🎜🎜eslint-loader🎜🎜🎜 eslint🎜🎜 🎜eslint-config-airbnb🎜🎜🎜eslint-plugin-import🎜🎜🎜eslint-フレンドリーフォーマッタ🎜🎜🎜eslint-plugin-flowtype🎜 🎜🎜eslint -plugin-jsx-a11y🎜🎜🎜eslint-plugin-react🎜🎜🎜babel-polyfill🎜🎜🎜webpack🎜🎜🎜 jest🎜🎜 🎜friends-errors-webpack-plugin コンパイルプロンプト用の Webpack プラグイン🎜🎜🎜html-webpack-plugin 作成用の Webpack プラグイン新しい HTML エントリ ファイル🎜🎜🎜copy-webpack-plugin webpack 構成マージ モジュール🎜🎜🎜webpack-merge webpack 構成マージ モジュール</ code>🎜</li>🎜🎜webpack-dev -server🎜</li>🎜🎜webpack-bundle-analyzer🎜</li>🎜🎜webpack-cli🎜</li>🎜🎜portfinder インターフェースを見つけるプラグイン🎜 </li>🎜🎜extract-text-webpack-plugin 🎜</li>🎜🎜node-notifier🎜</li>🎜🎜optimize-css-assets-webpack-plugin🎜</li>🎜🎜autoprefixer🎜</ li>🎜🎜mini-css-extract-plugin🎜</li>🎜🎜autoprefixer🎜</li>🎜🎜css-loader🎜</li>🎜🎜less-loader🎜</li>🎜🎜postcss-loader🎜 </li>🎜🎜postcss-import🎜</li>🎜🎜postcss-loader🎜</li>🎜🎜style-loader🎜</li>🎜🎜babel-core🎜</li>🎜🎜babel-eslint🎜 </li>🎜🎜babel-loader🎜</li >🎜🎜babel-plugin-transform-runtime🎜</li>🎜🎜babel-plugin-import🎜</li>🎜🎜babel-preset-env🎜</ li>🎜🎜babel-preset-react🎜</li>🎜🎜babel-polyfill🎜</li>🎜🎜url-loader🎜</li>🎜🎜cross-env🎜</li>🎜🎜file-loader🎜 </li></ul><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>resolve: { // 自动解析文件扩展名(补全文件后缀)(从左-&gt;右) // import hello from &amp;#39;./hello&amp;#39; (!hello.js? -&gt; !hello.jsx? -&gt; !hello.json) extensions: [&amp;#39;.js&amp;#39;, &amp;#39;.jsx&amp;#39;, &amp;#39;.json&amp;#39;], alias: { &amp;#39;@&amp;#39;: resolve(&amp;#39;src&amp;#39;) } },</pre><div class="contentsignin">ログイン後にコピー</div></div><div class="contentsignin">ログイン後にコピー</div></div>🎜プロジェクト構成🎜 🎜webpackの基本構成🎜🎜🎜🎜 開発環境と本番環境を制御するために、新しいビルドフォルダーを作成できます。開発環境と本番環境の Webpack 設定ファイルを別々に記述することで、本番環境と開発環境を個別に制御することが容易になります。 🎜</li>🎜🎜 コードの再利用率を向上させ、<code>基本構成個人用構成を区別するために、新しい webpack.base< を作成できます。 /code それぞれ >、<code>webpack.dev、および webpack.prod の 3 つの構成ファイル。まず、最も基本的な入力と出力を構成します。 🎜
      noParse: function(content) {
        return /jquery|lodash/.test(content);
      }
      ログイン後にコピー
      ログイン後にコピー

      entry

      🎜entry はそれぞれ文字列、配列、オブジェクトにすることができます。 🎜🎜アプリケーションにエントリが 1 つしかない場合、エントリ値はどのようなタイプでもよく、出力結果には影響しません。 🎜
      module: {
          rules: [
          {
              test: /\.(js|jsx)$/,
              exclude: /node_modules/,
              enforce: &#39;pre&#39;,
              use: [{
                loader: &#39;babel-loader&#39;,
              }, {
                loader: &#39;eslint-loader&#39;, // 指定启用eslint-loader
                options: {
                  formatter: require(&#39;eslint-friendly-formatter&#39;),
                  emitWarning: false
                }
              }]
            },
          {
              test: /\.css$/,
              include: /node_modules/,
              use: [
                MiniCssExtractPlugin.loader,
                &#39;css-loader&#39;,
                {
                  loader: &#39;postcss-loader&#39;,
                  options: {
                    plugins: () => [autoprefixer({ browsers: &#39;last 5 versions&#39; })],
                    sourceMap: false,
                  },
                },
              ],
            },
            {
              test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
              loader: &#39;url-loader&#39;,
              options: {
                limit: 10000,
                name: (&#39;assets/img/[name].[hash:7].[ext]&#39;)
              }
            },
            {
              test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
              loader: &#39;url-loader&#39;,
              options: {
                limit: 10000,
                name: (&#39;assets/media/[name].[hash:7].[ext]&#39;)
              }
            },
            {
              test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
              loader: &#39;url-loader&#39;,
              options: {
                limit: 10000,
                name: (&#39;assets/fonts/[name].[hash:7].[ext]&#39;)
              }
            }
          ]
          }
      ログイン後にコピー
      ログイン後にコピー
      // package.json
      "scripts": {
          "start": "webpack-dev-server --mode development --config build/webpack.dev.conf.js",
      }
      // 设置当前的mode为development,同样这个配置也可以写在webpack.dev.conf.js中。然后使用build目录下的webpack.dev.conf.js 来配置相关的webpack。
      ログイン後にコピー
      ログイン後にコピー
      devServer: {
          clientLogLevel: &#39;warning&#39;,
          historyApiFallback: true, //在开发单页应用时非常有用,它依赖于HTML5 history API,如果设置为true,所有的跳转将指向index.html
          contentBase: path.resolve(__dirname, &#39;../src&#39;),
          compress: true,
          hot: true, // 热加载
          inline: true, //自动刷新
          open: true, //自动打开浏览器
          host: HOST||&#39;localhost&#39;,
          port: PORT,
          overlay: { warnings: false, errors: true }, // 在浏览器上全屏显示编译的errors或warnings。
          publicPath: &#39;/&#39;,
          proxy: {},
          quiet: true, // necessary for FriendlyErrorsPlugin // 终端输出的只有初始启动信息。 webpack 的警告和错误是不输出到终端的
          watchOptions: {
            poll: false
          }
        },
        plugins: [
          new webpack.DefinePlugin({
            ...process.env
          }),
          //开启HMR(热替换功能,替换更新部分,不重载页面!)
          new webpack.HotModuleReplacementPlugin(),// HMR shows correct file names in console on update.
          //显示模块相对路径
          new webpack.NamedModulesPlugin(),
          //不显示错误信息
          new webpack.NoEmitOnErrorsPlugin(),
          // https://github.com/ampedandwired/html-webpack-plugin
          ]
      ログイン後にコピー
      ログイン後にコピー
      🎜 webpack を使用して複数のページを構築する方法については、この記事を参照してください。ただし、webpack 4.x は崖っぷちのアップグレードでもあり、興味のある学生は自分で検索できます。 🎜
      // 设置代码分离的输出目录
      output: {
          path: path.resolve(__dirname, &#39;../dist&#39;),
          filename: (&#39;js/[name].[hash:8].js&#39;),
          chunkFilename: (&#39;js/[name]-[id].[hash:8].js&#39;)
        },
       // 代码分离
       optimization: {
          runtimeChunk: {
            name: "manifest"
          },
          splitChunks: {
            chunks: &#39;all&#39;
          }
        },
      ログイン後にコピー
      ログイン後にコピー

      🎜CommonsChunkPlugin は webpack 4.0 の後に削除されました。代わりに、splitChunksPlugin を使用できます。 🎜

      出力

      🎜 出力の 2 つの最も基本的な構成は、pathfilename です。 🎜
        🎜 🎜path は、出力ディレクトリの場所を webpack に伝えます。一般に、dist フォルダーをルート ディレクトリに設定します。 code > 出力ファイルのファイル名を指定するために使用されます。複数の個別の chunk が設定されている場合、プレースホルダー [name].[hash] を使用して、それぞれを確認できます。ファイルには一意の名前が付いています。
      • 另一个常见配置 publicPath 则是用于更加复杂的场景。举例:在本地时,你可能会使用 ../assets/test.png 这种url来载入图片。而在生产环境下,你可能会使用CDN或者图床的地址。那么就需要配置 publicPath = "http://cdn.example.com/assets/" 来实现生产模式下编译输出文件时自动更新url。

       output: {
          path: path.resolve(__dirname, &#39;../dist&#39;),
          filename: &#39;[name].[hash:8].js&#39;,
          publicPath: &#39;/&#39;,
        },
      ログイン後にコピー
      ログイン後にコピー

      resolve

      resolve常用的两个配置为 aliasextensions

      • alias 创建import或者require的别名

      • extensins 自动解析文件拓展名,补全文件后缀

      resolve: {
          // 自动解析文件扩展名(补全文件后缀)(从左->右)
          // import hello from &#39;./hello&#39;  (!hello.js? -> !hello.jsx? -> !hello.json)
          extensions: [&#39;.js&#39;, &#39;.jsx&#39;, &#39;.json&#39;],
          alias: {
            &#39;@&#39;: resolve(&#39;src&#39;)
          }
        },
      ログイン後にコピー
      ログイン後にコピー

      module

      module的选项决定了如何处理项目中的不同类型的模块。其中常用的有 rulesnoParese 两个配置项。

      • noParese 是为了防止weback解析与所有与rule相匹配的文件。目的是,忽略大型的library可以提高构建性能。

      noParse: function(content) {
        return /jquery|lodash/.test(content);
      }
      ログイン後にコピー
      ログイン後にコピー
      • rules 用于在创建模块是,匹配规则数组,以确定哪些规则能够对module应用loader,或者是修改parser。

      module: {
          rules: [
          {
              test: /\.(js|jsx)$/,
              exclude: /node_modules/,
              enforce: &#39;pre&#39;,
              use: [{
                loader: &#39;babel-loader&#39;,
              }, {
                loader: &#39;eslint-loader&#39;, // 指定启用eslint-loader
                options: {
                  formatter: require(&#39;eslint-friendly-formatter&#39;),
                  emitWarning: false
                }
              }]
            },
          {
              test: /\.css$/,
              include: /node_modules/,
              use: [
                MiniCssExtractPlugin.loader,
                &#39;css-loader&#39;,
                {
                  loader: &#39;postcss-loader&#39;,
                  options: {
                    plugins: () => [autoprefixer({ browsers: &#39;last 5 versions&#39; })],
                    sourceMap: false,
                  },
                },
              ],
            },
            {
              test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
              loader: &#39;url-loader&#39;,
              options: {
                limit: 10000,
                name: (&#39;assets/img/[name].[hash:7].[ext]&#39;)
              }
            },
            {
              test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
              loader: &#39;url-loader&#39;,
              options: {
                limit: 10000,
                name: (&#39;assets/media/[name].[hash:7].[ext]&#39;)
              }
            },
            {
              test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
              loader: &#39;url-loader&#39;,
              options: {
                limit: 10000,
                name: (&#39;assets/fonts/[name].[hash:7].[ext]&#39;)
              }
            }
          ]
          }
      ログイン後にコピー
      ログイン後にコピー

      例如上述代码,就使用eslint-lodaerbabel-loader 处理了除了node_modules 以外的 js||jsx。同时配置了,解析图片、视频、字体文件等的解析,当rules匹配到的文件时,小于10000 byte 时,采用url-loader解析文件。(因为base64会让图片的体积变大,所以当文件较大时,使用base64并不明智)

      Webpack开发配置

      因为在webpack 4.X 中使用了流行的 ”约定大于配置“ 的做法,所以在新加入配置项 mode ,可以告知webpack使用相应模式的内置优化。

      选项描述
      development会将process.env.NODE_ENV 的值设为 development 。启用NamedChunksPluginNamedMoudulesPlugin
      production会将process.env.NODE_ENV 的值设为 production 。启用FlagDependencyUsagePluginFlagIncludedChunksPluginModuleConcatenationPluginNoEmitOnErrorsPluginOccurrenceOrderPluginSideEffectsFlagPluginUglifyJsPlugin

      如果我们只设置NODE_ENV,则不会自动设置 mode

      在开发时,我们往往希望能看到当前开发的页面,并且能热加载。这时,我们可以借助webpack-dev-server 这个插件,来在项目中起一个应用服务器。

      // package.json
      "scripts": {
          "start": "webpack-dev-server --mode development --config build/webpack.dev.conf.js",
      }
      // 设置当前的mode为development,同样这个配置也可以写在webpack.dev.conf.js中。然后使用build目录下的webpack.dev.conf.js 来配置相关的webpack。
      ログイン後にコピー
      ログイン後にコピー
      devServer: {
          clientLogLevel: &#39;warning&#39;,
          historyApiFallback: true, //在开发单页应用时非常有用,它依赖于HTML5 history API,如果设置为true,所有的跳转将指向index.html
          contentBase: path.resolve(__dirname, &#39;../src&#39;),
          compress: true,
          hot: true, // 热加载
          inline: true, //自动刷新
          open: true, //自动打开浏览器
          host: HOST||&#39;localhost&#39;,
          port: PORT,
          overlay: { warnings: false, errors: true }, // 在浏览器上全屏显示编译的errors或warnings。
          publicPath: &#39;/&#39;,
          proxy: {},
          quiet: true, // necessary for FriendlyErrorsPlugin // 终端输出的只有初始启动信息。 webpack 的警告和错误是不输出到终端的
          watchOptions: {
            poll: false
          }
        },
        plugins: [
          new webpack.DefinePlugin({
            ...process.env
          }),
          //开启HMR(热替换功能,替换更新部分,不重载页面!)
          new webpack.HotModuleReplacementPlugin(),// HMR shows correct file names in console on update.
          //显示模块相对路径
          new webpack.NamedModulesPlugin(),
          //不显示错误信息
          new webpack.NoEmitOnErrorsPlugin(),
          // https://github.com/ampedandwired/html-webpack-plugin
          ]
      ログイン後にコピー
      ログイン後にコピー

      其实在开发时,我们可以设置 contentBase: &#39;/src&#39;contentBase 指定了devServer能访问的资源地址。因为我们开发时,资源大部分都放在src目录下,所以可以直接指定资源路径为src目录。因为我们在webpack基础配置时,配置了 output 输出为 dist 目录,所以我们也可以在devServer里,设置 contentBasedist 目录。不过此时需要使用copyWebpackPlugin将一些静态资源复制到 dist 目录下,手动新建dist目录,并复制也可以。

      另外,当使用 history 路由时,要配置 historyApiFallback = true ,以此让服务器放弃路由权限,交由前端路由。而是用 hash 路由则不需要此配置。

      项目进阶

      生产环境配置

      在使用webpack 4.x 的 mode 配置之后,需要我们手动配置的项已经减少了很多,像js代码压缩这种工具 UglifyJsPlugin 就已经不用手动去配置。但是像很多前面提到的 代码分离css代码提取和压缩html的生成 以及 复制静态资源 还需要我们手动配置。

      代码分离

      // 设置代码分离的输出目录
      output: {
          path: path.resolve(__dirname, &#39;../dist&#39;),
          filename: (&#39;js/[name].[hash:8].js&#39;),
          chunkFilename: (&#39;js/[name]-[id].[hash:8].js&#39;)
        },
       // 代码分离
       optimization: {
          runtimeChunk: {
            name: "manifest"
          },
          splitChunks: {
            chunks: &#39;all&#39;
          }
        },
      ログイン後にコピー
      ログイン後にコピー

      css代码压缩

      借助 MiniCssExtractPlugin 来实现压缩css和提取css。因为 MiniCssExtractPlugin 无法与style-loader 共存,所以我们需要判断当前环境是生成环境还是开发环境。

      我们可以新建一个util.js的文件,在webpack当中一些共用的方法。考虑使用个别配置字段 extract 来配置使用何种方式来配置css-loader。参见 util.js 代码。

      new MiniCssExtractPlugin({
            filename: &#39;css/[name].[hash:8].css&#39;,
            chunkFilename: &#39;css/[name]-[id].[hash:8].css&#39;,
          }),
      ログイン後にコピー

      生成HTML

      使用htmlWebpackPlugin,配合ejs。可以使控制html 的生成。通过配置的方式,生成html。因为 HtmlWebpackPlugin 本身可以解析ejs,所以不需要单独引入ejs的loader。

      new HtmlWebpackPlugin({
            filename: &#39;index.html&#39;,
            template: &#39;./src/index.ejs&#39;, // 设置目录
            title: &#39;React Demo&#39;,
            inject: true, // true->&#39;head&#39; || false->&#39;body&#39;
            minify: {
              //删除Html注释
              removeComments: true,
              //去除空格
              collapseWhitespace: true,
              //去除属性引号
              removeAttributeQuotes: true
              // more options:
              // https://github.com/kangax/html-minifier#options-quick-reference
            },
            // necessary to consistently work with multiple chunks via CommonsChunkPlugin
            chunksSortMode: &#39;dependency&#39;
          }),
      ログイン後にコピー
      <!DOCTYPE html>
      <html>
      <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta name="robots" content="noindex, nofollow">
      
        <title><%= htmlWebpackPlugin.options.title %></title>
        <link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
        <link rel="icon" href="/favicon.ico" type="image/x-icon">
      
        <% for (var chunk in htmlWebpackPlugin.files.css) { %>
        <link rel="preload" href="<%= htmlWebpackPlugin.files.css[chunk] %>"  as="style">
        <% } %>
        <% for (var chunk in htmlWebpackPlugin.files.chunks) { %>
        <link rel="preload" href="<%= htmlWebpackPlugin.files.chunks[chunk].entry %>" as="script">
        <% } %>
      
        <base href="/">
      </head>
      <body>
      <p id="root"></p>
      </body>
      <style type="text/css">
        body {
          font-family: &#39;Source Sans Pro&#39;,&#39;Helvetica Neue&#39;,Helvetica,Arial,sans-serif;
        }
      </style>
      </html>
      ログイン後にコピー

      复制静态目录

      将所以可能被请求的静态文件,分别放在assets目录下。那么在打包后,为了保证目录能正常访问(不使用CDN等加载静态资源时),我们可以配置 publicPath = &#39;/&#39; 。然后借助于 CopyWebpackPlugin 实现资源复制。

      new CopyWebpackPlugin([{
            from: &#39;./src/assets/&#39;,
            to: &#39;assets&#39;
          }]),
      ログイン後にコピー

      src/assets 复制到 dist/assets 目录下

      开启打包分析

      借助插件 BundleAnalyzerPlugin 直接在plugins中创建该插件:

      // webpack.prod.conf.js
      const BundleAnalyzerPlugin = process.env.NODE_ENV=== &#39;analysis&#39; ? require(&#39;webpack-bundle-analyzer&#39;).BundleAnalyzerPlugin:null
      process.env.NODE_ENV=== &#39;analysis&#39; ? new BundleAnalyzerPlugin() : ()=>{}
      ログイン後にコピー

      在package.json 中可做如下配置:

      "scripts": {
          "analysis": "cross-env NODE_ENV=analysis webpack -p --mode production --progress --config ./build/webpack.prod.conf.js ",
        },
      ログイン後にコピー

      通过注入环境变量,来控制是否运行打包分析。

      ssh部署

      打包后的dist文件夹,可以直接借助 node 的 ssh-node ,直接部署到服务器指定的目录下。 ssh-node既支持ssh,也支持密码登录。建议可以为在每个项目下,新建一个.ssh文件,存放项目的私钥。代码如下:

      // usage: https://www.npmjs.com/package/node-ssh
      var path, node_ssh, ssh, fs, opn, host
      
      fs = require(&#39;fs&#39;)
      path = require(&#39;path&#39;)
      node_ssh = require(&#39;node-ssh&#39;)
      opn = new require(&#39;opn&#39;)
      ssh = new node_ssh()
      host = &#39;localhost&#39;
      var localDir = &#39;./dist&#39;
      var remoteDir = &#39;/opt/frontend/new&#39;
      var removeCommand = &#39;rm -rf ./*&#39;
      var pwdCommand = &#39;pwd&#39;
      
      ssh.connect({
        host: host,
        username: &#39;root&#39;,
        port: 22,
        // password,
        privateKey: "./.ssh/id_rsa",
      })
        .then(function() {
          ssh.execCommand(removeCommand, { cwd:remoteDir }).then(function(result) {
            console.log(&#39;STDOUT: &#39; + result.stdout)
            console.log(&#39;STDERR: &#39; + result.stderr)
            ssh.putDirectory(localDir, remoteDir).then(function() {
              console.log("The File thing is done")
              ssh.dispose()
              opn(&#39;http://&#39;+host, {app:[&#39;chrome&#39;]})
            }, function(error) {
              console.log("Something&#39;s wrong")
              console.log(error)
              ssh.dispose()
            })
          })
        })
      ログイン後にコピー

      此时,在命令行直接 node deploy.js 就可以运行以上脚本,我们也可以添加一个build + deploy的script脚本,便于启动。

      "scripts": {
          "depoly": "npm run build && node ./deploy.js",
      }
      ログイン後にコピー

      相关推荐:

      详解React 快速上手脚手架 create-react-app

      简单搭建一个react项目

      以上がwebpack4 に基づいて反応スキャフォールディングを構築する方法のプロセス分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

独自のJavaScriptライブラリを作成および公開するにはどうすればよいですか? 独自のJavaScriptライブラリを作成および公開するにはどうすればよいですか? Mar 18, 2025 pm 03:12 PM

記事では、JavaScriptライブラリの作成、公開、および維持について説明し、計画、開発、テスト、ドキュメント、およびプロモーション戦略に焦点を当てています。

ブラウザでのパフォーマンスのためにJavaScriptコードを最適化するにはどうすればよいですか? ブラウザでのパフォーマンスのためにJavaScriptコードを最適化するにはどうすればよいですか? Mar 18, 2025 pm 03:14 PM

この記事では、ブラウザでJavaScriptのパフォーマンスを最適化するための戦略について説明し、実行時間の短縮、ページの負荷速度への影響を最小限に抑えることに焦点を当てています。

フロントエンドのサーマルペーパーレシートのために文字化けしたコード印刷に遭遇した場合はどうすればよいですか? フロントエンドのサーマルペーパーレシートのために文字化けしたコード印刷に遭遇した場合はどうすればよいですか? Apr 04, 2025 pm 02:42 PM

フロントエンドのサーマルペーパーチケット印刷のためのよくある質問とソリューションフロントエンド開発におけるチケット印刷は、一般的な要件です。しかし、多くの開発者が実装しています...

ブラウザ開発者ツールを使用してJavaScriptコードを効果的にデバッグするにはどうすればよいですか? ブラウザ開発者ツールを使用してJavaScriptコードを効果的にデバッグするにはどうすればよいですか? Mar 18, 2025 pm 03:16 PM

この記事では、ブラウザ開発者ツールを使用した効果的なJavaScriptデバッグについて説明し、ブレークポイントの設定、コンソールの使用、パフォーマンスの分析に焦点を当てています。

ソースマップを使用して、マイナイドJavaScriptコードをデバッグするにはどうすればよいですか? ソースマップを使用して、マイナイドJavaScriptコードをデバッグするにはどうすればよいですか? Mar 18, 2025 pm 03:17 PM

この記事では、ソースマップを使用して、元のコードにマッピングすることにより、Minified JavaScriptをデバッグする方法について説明します。ソースマップの有効化、ブレークポイントの設定、Chrome DevtoolsやWebpackなどのツールの使用について説明します。

初心者向けのタイプスクリプト、パート2:基本データ型 初心者向けのタイプスクリプト、パート2:基本データ型 Mar 19, 2025 am 09:10 AM

エントリーレベルのタイプスクリプトチュートリアルをマスターしたら、TypeScriptをサポートするIDEで独自のコードを作成し、JavaScriptにコンパイルできるはずです。このチュートリアルは、TypeScriptのさまざまなデータ型に飛び込みます。 JavaScriptには、NULL、未定義、ブール値、数字、文字列、シンボル(ES6によって導入)とオブジェクトの7つのデータ型があります。 TypeScriptはこれに基づいてより多くのタイプを定義し、このチュートリアルではすべてを詳細に説明します。 ヌルデータ型 JavaScriptのように、Typescriptのnull

Javaのコレクションフレームワークを効果的に使用するにはどうすればよいですか? Javaのコレクションフレームワークを効果的に使用するにはどうすればよいですか? Mar 13, 2025 pm 12:28 PM

この記事では、Javaのコレクションフレームワークの効果的な使用について説明します。 データ構造、パフォーマンスのニーズ、スレッドの安全性に基づいて、適切なコレクション(リスト、セット、マップ、キュー)の選択を強調しています。 コレクションの使用を効率的に最適化します

chart.js:パイ、ドーナツ、バブルチャートを始めます chart.js:パイ、ドーナツ、バブルチャートを始めます Mar 15, 2025 am 09:19 AM

このチュートリアルでは、chart.jsを使用してパイ、リング、およびバブルチャートを作成する方法について説明します。以前は、4つのチャートタイプのchart.js:ラインチャートとバーチャート(チュートリアル2)、およびレーダーチャートと極地域チャート(チュートリアル3)を学びました。 パイとリングチャートを作成します パイチャートとリングチャートは、さまざまな部分に分かれている全体の割合を示すのに理想的です。たとえば、パイチャートを使用して、サファリの男性ライオン、女性ライオン、若いライオンの割合、または異なる候補者が選挙で受け取る票の割合を示すことができます。 パイチャートは、単一のパラメーターまたはデータセットの比較にのみ適しています。パイチャートのファンの角度はデータポイントの数値サイズに依存するため、パイチャートは値のあるエンティティをゼロ値で描画できないことに注意してください。これは、割合がゼロのエンティティを意味します

See all articles