목차
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. Configuration .editorconfig는 IDE를 통합합니다. (코드 참조)

  2. .editorconfig 使得IDE的方式统一 (见代码)
  3. 配置 .eslintrc.js 使得代码规范统一 (见代码)

    预期功能

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

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

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

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

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

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

  10. 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]

    .eslintrc.js를 구성하여 코드 사양 통합(코드 참조)#🎜🎜##🎜🎜#예상되는 기능 #🎜🎜#
  • #🎜🎜##🎜🎜#리소스 관리: CSS, sccc, less 및 정적 파일을 로드할 수 있습니다. #🎜🎜##🎜🎜##🎜🎜#출력 관리: 패키지된 정적 파일은 정적 디렉터리에 출력되고 해당 파일 유형에 따라 관리됩니다#🎜🎜##🎜🎜##🎜🎜#dev: 소스 맵을 사용하여 디버깅 중 코드 위치 지정을 용이하게 합니다#🎜🎜# li>#🎜🎜##🎜🎜#dev: devServer 구성, 핫 교체, 핫 로딩, 자동 새로 고침 구성, 자동으로 브라우저 열기 및 ProxyTable 예약#🎜🎜##🎜🎜##🎜 🎜 #dev: 기본적으로 8080을 열도록 설정되어 있으면 다음 빈 인터페이스를 찾습니다. #🎜🎜##🎜🎜##🎜🎜#production: 코드 분리, CSS 파일 패키징, CSS 코드 압축, js 코드 압축, 출력 템플릿 html로 이동하여 gzip을 구성합니다#🎜🎜##🎜🎜##🎜🎜#analytic:: BundleAnalyzerPlugin을 사용하여 패키지 성능 분석#🎜🎜##🎜🎜# 디렉터리 구조#🎜🎜#
      #🎜🎜##🎜🎜#먼저 npm init를 사용하여 package.json이 포함된 루트 디렉터리를 초기화합니다#🎜🎜 #
     output: {
        path: path.resolve(__dirname, '../dist'),
        filename: '[name].[hash:8].js',
        publicPath: '/',
      },
    로그인 후 복사
    로그인 후 복사
    #🎜🎜#종속성 설치#🎜🎜#
      #🎜🎜##🎜🎜#eslint-loader#🎜🎜##🎜🎜##🎜🎜#eslint #🎜🎜##🎜🎜##🎜🎜#eslint-config-airbnb#🎜🎜##🎜🎜##🎜🎜#eslint-plugin -import#🎜🎜# #🎜🎜##🎜🎜#eslint-Friendly-formatter#🎜🎜##🎜🎜##🎜🎜#eslint-plugin-flowtype#🎜🎜# li>#🎜🎜##🎜🎜# eslint-plugin-jsx-a11y#🎜🎜##🎜🎜##🎜🎜#eslint-plugin-react#🎜🎜##🎜🎜# #🎜🎜#babel-polyfill#🎜🎜 ##🎜🎜##🎜🎜#webpack#🎜🎜##🎜🎜##🎜🎜#jest#🎜🎜## 🎜🎜##🎜🎜#friend-errors -webpack-plugin 컴파일 프롬프트용 Webpack 플러그인#🎜🎜##🎜🎜##🎜🎜#html-webpack-plugin < code>새 html 항목 파일용 Webpack 플러그인#🎜🎜##🎜🎜##🎜🎜#copy-webpack-plugin webpack 구성 병합 모듈#🎜🎜 ##🎜🎜##🎜🎜#webpack -merge webpack 구성 병합 모듈#🎜🎜##🎜🎜##🎜🎜#webpack-dev-server#🎜 🎜##🎜🎜##🎜🎜# webpack-bundle-analyzer#🎜🎜##🎜🎜##🎜🎜#webpack-cli#🎜🎜##🎜🎜# #🎜🎜#portfinder 인터페이스를 찾는 플러그인#🎜🎜#< /li>#🎜🎜##🎜🎜#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#🎜🎜#< /li>#🎜🎜##🎜🎜#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#🎜🎜#< /li>#🎜🎜##🎜🎜#url-loader#🎜🎜##🎜🎜##🎜🎜#cross-env #🎜🎜##🎜🎜##🎜🎜#file -loader#🎜🎜#
    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;)
        }
      },
    로그인 후 복사
    로그인 후 복사
    #🎜🎜#프로젝트 구성#🎜🎜##🎜🎜#webpack 기본 구성# 🎜🎜##🎜🎜##🎜🎜##🎜🎜#For control 개발 환경과 프로덕션 환경을 위해 새로운 빌드 폴더를 생성할 수 있습니다. 개발 환경과 프로덕션 환경에 대한 웹팩 구성 파일을 별도로 작성하면 프로덕션 환경과 개발 환경을 별도로 제어하기가 더 쉬워집니다. #🎜🎜##🎜🎜##🎜🎜#코드 재사용률을 높이고 기본 구성맞춤 구성을 구분하려면 별도로 새 파일을 생성할 수 있습니다. 세 가지 구성 파일: webpack.base, webpack.devwebpack.prod. 먼저 가장 기본적인 입력과 출력을 구성합니다. #🎜🎜#
    noParse: function(content) {
      return /jquery|lodash/.test(content);
    }
    로그인 후 복사
    로그인 후 복사

    entry

    #🎜🎜#entry는 각각 문자열, 배열 및 객체일 수 있습니다. #🎜🎜##🎜🎜#응용 프로그램에 단일 항목만 있는 경우 항목 값은 모든 유형이 될 수 있으며 출력 결과에 영향을 미치지 않습니다. #🎜🎜#
    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을 사용할 수 있습니다. #🎜🎜#

    출력

    #🎜🎜#출력의 가장 기본적인 두 가지 구성은 pathfilename입니다. #🎜🎜#
      #🎜🎜##🎜🎜#path는 webpack에 출력 디렉터리가 어디에 있는지 알려줍니다. 일반적으로 루트에 dist 폴더를 설정합니다. ;#🎜🎜##🎜🎜##🎜🎜#filename은 출력 파일의 파일 이름을 지정하는 데 사용됩니다. 구성된 경우 여러 개의 개별 청크</code code>가 생성되었습니다. > <code>[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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 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 Hentai를 무료로 생성하십시오.

인기 기사

R.E.P.O. 에너지 결정과 그들이하는 일 (노란색 크리스탈)
2 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 최고의 그래픽 설정
2 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 아무도들을 수없는 경우 오디오를 수정하는 방법
2 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

JavaScript로 문자열 문자를 교체하십시오 JavaScript로 문자열 문자를 교체하십시오 Mar 11, 2025 am 12:07 AM

JavaScript 문자열 교체 방법 및 FAQ에 대한 자세한 설명 이 기사는 JavaScript에서 문자열 문자를 대체하는 두 가지 방법 인 내부 JavaScript 코드와 웹 페이지의 내부 HTML을 탐색합니다. JavaScript 코드 내부의 문자열을 교체하십시오 가장 직접적인 방법은 대체 () 메소드를 사용하는 것입니다. str = str.replace ( "find", "replace"); 이 메소드는 첫 번째 일치 만 대체합니다. 모든 경기를 교체하려면 정규 표현식을 사용하고 전역 플래그 g를 추가하십시오. str = str.replace (/fi

자신의 Ajax 웹 응용 프로그램을 구축하십시오 자신의 Ajax 웹 응용 프로그램을 구축하십시오 Mar 09, 2025 am 12:11 AM

그래서 여기 당신은 Ajax라는이 일에 대해 배울 준비가되어 있습니다. 그러나 정확히 무엇입니까? Ajax라는 용어는 역동적이고 대화식 웹 컨텐츠를 만드는 데 사용되는 느슨한 기술 그룹을 나타냅니다. 원래 Jesse J에 의해 만들어진 Ajax라는 용어

10 JQuery Fun 및 Games 플러그인 10 JQuery Fun 및 Games 플러그인 Mar 08, 2025 am 12:42 AM

10 재미있는 jQuery 게임 플러그인 웹 사이트를보다 매력적으로 만들고 사용자 끈적함을 향상시킵니다! Flash는 여전히 캐주얼 웹 게임을 개발하기위한 최고의 소프트웨어이지만 JQuery는 놀라운 효과를 만들 수 있으며 Pure Action Flash 게임과 비교할 수는 없지만 경우에 따라 브라우저에서 예기치 않은 재미를 가질 수 있습니다. jQuery tic 발가락 게임 게임 프로그래밍의 "Hello World"에는 이제 jQuery 버전이 있습니다. 소스 코드 jQuery Crazy Word Composition 게임 이것은 반은 반은 게임이며, 단어의 맥락을 알지 못해 이상한 결과를 얻을 수 있습니다. 소스 코드 jQuery 광산 청소 게임

내 자신의 JavaScript 라이브러리를 어떻게 작성하고 게시합니까? 내 자신의 JavaScript 라이브러리를 어떻게 작성하고 게시합니까? Mar 18, 2025 pm 03:12 PM

기사는 JavaScript 라이브러리 작성, 게시 및 유지 관리, 계획, 개발, 테스트, 문서 및 홍보 전략에 중점을 둡니다.

jQuery 시차 자습서 - 애니메이션 헤더 배경 jQuery 시차 자습서 - 애니메이션 헤더 배경 Mar 08, 2025 am 12:39 AM

이 튜토리얼은 jQuery를 사용하여 매혹적인 시차 배경 효과를 만드는 방법을 보여줍니다. 우리는 멋진 시각적 깊이를 만드는 계층화 된 이미지가있는 헤더 배너를 만들 것입니다. 업데이트 된 플러그인은 jQuery 1.6.4 이상에서 작동합니다. 다운로드

jQuery 및 Ajax를 사용한 자동 새로 고침 DIV 컨텐츠 jQuery 및 Ajax를 사용한 자동 새로 고침 DIV 컨텐츠 Mar 08, 2025 am 12:58 AM

이 기사에서는 jQuery 및 Ajax를 사용하여 5 초마다 DIV의 컨텐츠를 자동으로 새로 고치는 방법을 보여줍니다. 이 예제는 RSS 피드의 최신 블로그 게시물을 마지막 새로 고침 타임 스탬프와 함께 가져오고 표시합니다. 로딩 이미지는 선택 사항입니다

Matter.js : 소개를 시작합니다 Matter.js : 소개를 시작합니다 Mar 08, 2025 am 12:53 AM

Matter.js는 JavaScript로 작성된 2D 강성 신체 물리 엔진입니다. 이 라이브러리를 사용하면 브라우저에서 2D 물리학을 쉽게 시뮬레이션 할 수 있습니다. 그것은 단단한 몸체를 생성하고 질량, 면적 또는 밀도와 같은 물리적 특성을 할당하는 능력과 같은 많은 기능을 제공합니다. 중력 마찰과 같은 다양한 유형의 충돌 및 힘을 시뮬레이션 할 수도 있습니다. Matter.js는 모든 주류 브라우저를 지원합니다. 또한, 터치를 감지하고 반응이 좋기 때문에 모바일 장치에 적합합니다. 이러한 모든 기능을 사용하면 엔진 사용 방법을 배울 수있는 시간이 필요합니다. 이는 물리 기반 2D 게임 또는 시뮬레이션을 쉽게 만들 수 있습니다. 이 튜토리얼에서는 설치 및 사용을 포함한이 라이브러리의 기본 사항을 다루고

브라우저에서 성능을 위해 JavaScript 코드를 최적화하려면 어떻게해야합니까? 브라우저에서 성능을 위해 JavaScript 코드를 최적화하려면 어떻게해야합니까? Mar 18, 2025 pm 03:14 PM

이 기사는 브라우저에서 JavaScript 성능을 최적화하기위한 전략에 대해 설명하고 실행 시간을 줄이고 페이지로드 속도에 미치는 영향을 최소화하는 데 중점을 둡니다.

See all articles