>  기사  >  웹 프론트엔드  >  웹팩에서 스캐폴딩 최적화를 구현하는 방법

웹팩에서 스캐폴딩 최적화를 구현하는 방법

php中世界最好的语言
php中世界最好的语言원래의
2018-04-08 14:38:291722검색

이번에는 webpack에서 scaffolding 최적화를 구현하는 방법을 알려드리겠습니다. webpack에서 scaffolding 최적화를 위한 주의사항은 무엇인가요?

이전 글에서 webpack v4의 기능에 대해 배웠습니다. 이제 그 지식을 실제로 적용하여 이전에 작성한 React scaffold의 패키징 성능을 최적화해 보겠습니다.

최적화 카테고리

  1. 스타일 분리

  2. 서드 파티 리소스 분리

  3. 개발 환경 차별화

  4. 핫 업데이트

  5. 공개 코드 추출

1. CSS 분리

npm install extract-text-webpack-plugin -D

webpack.config.js

패키지 파일에서 css, less, sass 파일을 별도로 분리합니다.

+ let cssExtract = new ExtractTextWebpackPlugin({
+ filename: 'css.css',
+ allChunks: true
+ });
+ let sassExtract = new ExtractTextWebpackPlugin('sass.css')
+ let lessExtract = new ExtractTextWebpackPlugin('less.css')

webpack.config.js에 규칙을 별도로 추가합니다.

  1. test: 처리된 파일의 확장자와 일치합니다. 정규 표현식

  2. include/exclude는 처리해야 하는 폴더를 수동으로 지정하거나 처리할 필요가 없는 폴더를 차단합니다

{
 test: /\.css$/,
 use: cssExtract.extract({
 fallback: "style-loader",
 use: ['css-loader?minimize','postcss-loader'],
 publicPath: "/dist"
 }),
 include:path.join(dirname,'./src'),
 exclude:/node_modules/
},
{
 test: /\.scss$/,
 use: sassExtract.extract({
 fallback: "style-loader",
 use: ["css-loader?minimize","sass-loader"],
 publicPath: "/dist"
 }),
 include:path.join(dirname,'./src'),
 exclude:/node_modules/
},
{
 test: /\.less$/,
 loader: lessExtract.extract({
 use: ["css-loader?minimize", "less-loader"]
 }),
 include:path.join(dirname,'./src'),
 exclude:/node_modules/
},

그런 다음 webpack 명령을 실행하면 오류

컴파일이 보고됩니다. mainTemplate.applyPluginsWaterfall은 함수가 아닙니다

Chunks.groupsIterable을 사용하고 대신 Entrypoint 인스턴스로 필터링하세요

연구에 따르면 webpack은 v4로 업그레이드되었지만 해당 플러그인은 업그레이드되지 않았습니다.

해결책: 지정된 버전의 종속성을 설치합니다.

"html-webpack-plugin": "^3.0.4"
"extract-text-webpack-plugin": "^4.0.0-beta.0"

resolve

확장자를 지정한 후 require 또는 import 시 파일 확장자를 추가할 필요가 없습니다. 일치하도록 차례로 확장자를 추가하려고 시도합니다.

resolve: {
 //引入模块的时候,可以不用扩展名
 extensions: [".js", ".less", ".json"],
 alias: {//别名
 "bootstrap": "bootstrap/dist/css/bootstrap.css"
 }
}

파일 수정 모니터링

webpack 모드에서 사용되며 webpack-dev-server 모드에서는 사용되지 않으며 watch를 false로 변경할 수 있습니다.

watchOptions: {
 ignored: /node_modules/,
 aggregateTimeout: 300, //监听到变化发生后等300ms再去执行动作,防止文件更新太快导致编译频率太高
 poll: 1000 //通过不停的询问文件是否改变来判断文件是否发生变化,默认每秒询问1000次
}

공개 코드 추출

optimization: {
 splitChunks: {
 cacheGroups: {
 commons: {
  chunks: "initial",
  minChunks: 2,
  maxInitialRequests: 5, // The default limit is too small to showcase the effect
  minSize: 0 // This is example is too small to create commons chunks
 },
 vendor: {
  test: /node_modules/,
  chunks: "initial",
  name: "vendor",
  priority: 10,
  enforce: true
 }
 }
 }
 }

React React-dom ant Public 별도 code

방법 1: externals

페이지에 타사 리소스 라이브러리를 도입한 다음 외부를 사용하여 가져온 특정 패키지가 번들로 패키징되는 것을 방지합니다. 대신 런타임 시 외부에서 이러한 외부 종속성을 가져옵니다.

<script src="https://cdn.bootcss.com/react/16.4.0-alpha.0911da3/cjs/react.production.min.js"></script>
<script src="https://cdn.bootcss.com/react-dom/16.4.0-alpha.0911da3/cjs/react-dom-server.browser.production.min.js"></script>
externals: { 'react': 'React', 'react-dom': 'ReactDOM', // 提出ant design的公共资源, }

방법2: DLL

DLL은 이전글에서 작성했는데 패키징하고나서 계속 나오더라구요

나중에 해당 페이지에 리소스 소개가 안된걸 발견했습니다. . . . (저는 항상 webpack이 페이지에 자동으로 생성해준다고 생각했는데....)

index.html 파일에

<script src="./vendor/react.dll.js"></script>

를 추가해서 분리에 성공했습니다! 코드 업로드

webpack.base.js

var path = require('path');
var webpack = require('webpack');
var ExtractTextWebpackPlugin = require("extract-text-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const CleanWebpackPlugin = require('clean-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin')
let cssExtract = new ExtractTextWebpackPlugin({
 filename: 'css.css',
 allChunks: true
});
let sassExtract = new ExtractTextWebpackPlugin('sass.css')
let lessExtract = new ExtractTextWebpackPlugin('less.css')
module.exports = {
 entry:'./src/index.js',
 output: {
 path: path.resolve(dirname, './dist'),
 filename: 'bundle.[hash:8].js',
 publicPath: ''
 },
 resolve: {
 //引入模块的时候,可以不用扩展名
 extensions: [".js", ".less", ".json"],
 alias: {//别名
 "bootstrap": "bootstrap/dist/css/bootstrap.css"
 },
 modules: [path.resolve(dirname, 'node_modules')]
 },
/* externals: {
 'react': 'React',
 'react-dom': 'ReactDOM',
 // 提出ant design的公共资源
 //'antd': 'antd',
 },*/
 devtool: 'source-map',
 devServer: {
 contentBase:path.resolve(dirname,'dist'),
 publicPath: '/',
 port: 8080,
 hot:true,
 compress:true,
 historyApiFallback: true,
 inline: true
 },
 watch: false, //只有在开启监听模式时,watchOptions才有意义
 watchOptions: {
 ignored: /node_modules/,
 aggregateTimeout: 300, //监听到变化发生后等300ms再去执行动作,防止文件更新太快导致编译频率太高
 poll: 1000 //通过不停的询问文件是否改变来判断文件是否发生变化,默认每秒询问1000次
 },
 optimization: {
 splitChunks: {
 cacheGroups: {
 commons: {
  chunks: "initial",
  minChunks: 2,
  maxInitialRequests: 5, // The default limit is too small to showcase the effect
  minSize: 0 // This is example is too small to create commons chunks
 },
 vendor: {
  test: /node_modules/,
  chunks: "initial",
  name: "vendor",
  priority: 10,
  enforce: true
 }
 }
 }
 },
 module: {
 rules:[
 {
 test: /\.js$/,
 use: {
  loader:'babel-loader',
  options: {
  presets: ['env','es2015', 'react'],
  }
 },
 include:path.join(dirname,'./src'),
 exclude:/node_modules/
 },
 {
 test: /\.css$/,
 use: cssExtract.extract({
  fallback: "style-loader",
  use: ['css-loader?minimize','postcss-loader'],
  publicPath: "/dist"
 }),
 include:path.join(dirname,'./src'),
 exclude:/node_modules/
 },
 {
 test: /\.scss$/,
 use: sassExtract.extract({
  fallback: "style-loader",
  use: ["css-loader?minimize","sass-loader"],
  publicPath: "/dist"
 }),
 include:path.join(dirname,'./src'),
 exclude:/node_modules/
 },
 {
 test: /\.less$/,
 loader: lessExtract.extract({
  use: ["css-loader?minimize", "less-loader"]
 }),
 include:path.join(dirname,'./src'),
 exclude:/node_modules/
 },
 {
 test: /\.(html|htm)/,
 use: 'html-withimg-loader'
 },
 {
 test: /\.(png|jpg|gif|svg|bmp|eot|woff|woff2|ttf)/,
 use: {
  loader:'url-loader',
  options:{
  limit: 5 * 1024,
  //指定拷贝文件的输出目录
  outputPath: 'images/'
  }
 }
 }
 ]
 },
 plugins: [
 //定义环境变量
 new webpack.DefinePlugin({
 development: JSON.stringify(process.env.NODE_ENV)
 }),
 new CleanWebpackPlugin(['dist']),
 cssExtract,
 lessExtract,
 sassExtract,
 new HtmlWebpackPlugin({
 title: 'React Biolerplate by YuanYuan',
 template: './src/index.html',
 filename: `index.html`,
 hash: true
 }),
 new webpack.DllReferencePlugin({
 manifest: path.join(dirname, 'vendor', 'react.manifest.json')
 }),
 new CopyWebpackPlugin([{
 from: path.join(dirname,'vendor'),//静态资源目录源地址
 to:'./vendor' //目标地址,相对于output的path目录
 }]),
/* new webpack.optimize.CommonsChunkPlugin({
 name: 'common' // 指定公共 bundle 的名称。
 + })*/
 new webpack.HotModuleReplacementPlugin(), // 热替换插件
 new webpack.NamedModulesPlugin() // 执行热替换时打印模块名字
 ]
};

webpack.config.js

const path = require('path');
const webpack = require('webpack');
const merge = require('webpack-merge');//用来合并配置文件
const base = require('./webpack.base');
let other = '';
//console.log(process.env.NODE_ENV )
if (process.env.NODE_ENV == 'development') {
 other = require('./webpack.dev.config');
} else {
 other = require('./webpack.prod.config');
}
//console.log(merge(base, other));
module.exports = merge(base, other);
webpack.prod.config.js
const path = require('path');
const webpack = require('webpack');
const UglifyJSPlugin = require('uglifyjs-webpack-plugin')
module.exports = {
 output: {
 filename: 'bundle.min.js',
 },
 plugins: [
 new UglifyJSPlugin({sourceMap: true})
 ]
}

원래 스캐폴딩 주소

최적화된 스캐폴딩 주소

패키징 속도 최적화, 패키징 파일 미세 조정, 변환 성공~

이 기사의 사례를 읽은 후 방법을 마스터했다고 생각합니다. 더 흥미로운 정보를 보려면 PHP 중국어 웹사이트의 다른 관련 기사를 주목하세요!

추천 자료:

Vue 프로젝트를 환경별로 패키징하는 방법

React에서 Vuex를 사용하기 위한 구체적인 단계

위 내용은 웹팩에서 스캐폴딩 최적화를 구현하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.