webpack搭建vue最全深入分析,带您用合理的架子使
分类:前端技术

手摸手,带你用合理的架子使用webpack4(上)

2018/08/26 · 根底技艺 · webpack

原稿出处: 华尔街视线本事公司 - 花裤衩   

前几天 webpack 作者 Tobias Koppers 公布了风流洒脱篇新的文章 webpack 4.0 to 4.16: Did you know?(需翻墙卡塔尔国,总括了一下webpack 4揭露以来,做了什么样调度和优化。

何况说自个儿正在先河开采 webpack 5

Oh you are still on webpack 3. I’m sorry, what is blocking you? We already working on webpack 5, so your stack might be outdated soon…

翻译成汉语就是:

图片 1

恰巧作者也在行使一个文书档案生成工具 docz(安利一波卡塔尔国也低于须要webpack 4 ,新版webpack性情进步了成都百货上千,何况webpack 4 皆已宣告八个多月了,想必应该早已没什么坑了,应该能够安心的根据外人写的升官计策升级了。在此之前一贯缓慢不晋级完全部都以被2018年被 webpack 3 坑怕了。它在 code splitting 的场合下 CommonsChunkPlugin会全盘失效。过了好大器晚成段时间才修复,欲哭无泪。

进而本次大家了快大四个月才希图进级到webpack 4 但相对没悟出还是境遇了点不清的主题素材! 有不少从前遗留的标题还是不曾很好地消释。但最珍视的难题要么它的文书档案有所欠缺,已经废弃了的事物如commonsChunkPlugin还在法定文书档案中四处现身,超级多主要的事物却一笔带过,以致没写,要求顾客本身去看源码技巧化解。

还举个例子在v4.16.0本子中吐弃了 optimization.occurrenceOrderoptimization.namedChunksoptimization.hashedModuleIdsoptimization.namedModules 那多少个构造项,替换到了optimization.moduleIdsoptimization.chunkIds,但文书档案完全中学全未有其余显示,所以你在新本子中还依据文档那样安插其实是没有其他功用的。

风行最完全的文书档案仍旧看她项指标布置WebpackOptions.json,刚烈提出遇到不驾驭的布署项能够看那些,因为它必然保障是和新型代码同步的。

嘲弄了那样多,大家言归正传。由于此次手摸手篇幅有些长,所以拆解成了左右两篇文章:

  • 上篇 — 正是管见所及的在webpack 3的根底上升高,要做如何操作和遭受了何等坑
  • 下篇 — 是在webpack 4下怎么合理的包装和拆包,何况如何最大化利用 long term caching

本小说不是手摸手从零教你 webpack 配置,所以并不会讲太多很根底的配置难点。比如如何处理 css 文件,怎么样布置 webpack-dev-server,陈述 file-loader 和 url-loader 之间的分别等等,有须要的推荐介绍看 官方文书档案 或者 survivejs 出的一个五花八门教程。也许推荐看作者司的另生机勃勃篇 wbepack 入门随笔,已同步到 webpack4 传送门。

原标题:vue-cli webpack搭建vue最全深入分析

黄金时代、模块化系统产生:

转发请注脚原版的书文者以至链接,谢谢!

升级篇

一、vue-cli介绍

vue-cli是叁个依照nodeJs、用于火速搭建vue项目标 脚手架。

二、vue-cli安装、更新

安装过nodeJs 、cnpm 后,全局安装vue-cli(今后别的类型可径直利用):

cnpm install -g vue-cli

更新:

cnpm update vue-cli

查阅安装成功否(有版本号正是打响,V大写)

vue -V

查阅npm注册表里vue-cli版本号:

cnpm view vue-cli

三、vue-cli 使用

安装过webpack 、vue-cli后,能够初叶搭建vue项目:

vue init webpack <Project Name>

eg:右击Git Base Here(如若您未有用git ,你也得以按住shift键右击接纳“在这里处张开命令窗口”,大概 cmd :cd project/lfxProject),如图:

图片 2or

ps:ESLint(三个java代码检查评定工具卡塔尔国、unit tests(单元测量检验卡塔尔国、Nightwatch(七个e2e客户分界面测量检验工具)。

四、项目成功

类型构造如下:

图片 3

各文件成效解析,如下:

1、build文件夹:

build文件夹的布局:

图片 4

(1)build.js

'use strict'

require('./check-versions'卡塔尔(卡塔尔(قطر‎ //调用版本检查

process.env.NODE_ENV = 'production' //将意况安插为生产条件

const ora = require('ora') //npm包 loading插件

const rm = require('rimraf'卡塔尔(قطر‎ //npm包 用于删除文件

const path = require('path'卡塔尔//npm包 文件路线工具

const chalk = require('chalk'卡塔尔国//npm包 在终端输出带颜色的文字

const webpack = require('webpack')//引入webpack.js

const config = require('../config'卡塔尔国//引进配置文件

const webpackConfig = require('./webpack.prod.conf'卡塔尔(قطر‎//引进坐褥条件布署文件

// 在尖峰显示loading效果,并出口提醒

const spinner = ora('building for production...')

spinner.start()

//先递归删除dist文件再生成新文件,制止冗余

rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {

if (err) throw err

webpack(webpackConfig, (err, stats) => {

spinner.stop()

if (err) throw err

process.stdout.write(stats.toString({

colors: true,

modules: false,

children: false,

chunks: false,

chunkModules: false

}) 'nn')

if (stats.hasErrors()) {

console.log(chalk.red(' Build failed with errors.n'))

process.exit(1)

}

console.log(chalk.cyan(' Build complete.n'))

console.log(chalk.yellow(

' Tip: built files are meant to be served over an HTTP server.n'

' Opening index.html over file:// won't work.n'

))

})

})

ps:require/export是风姿罗曼蒂克种nodeJs(commonJs标准卡塔尔(英语:State of Qatar)的信任性注入的不二诀窍,import/export是ES6语法,用于引进模块,在nodeJs中接收的ES6语法最后会利用babel工具(babel-loader)转变为ES5

(2)check-version.js:质量评定node和npm的本子,完成版本信任

'use strict'

const chalk = require('chalk')

const semver = require('semver'卡塔尔国//检查版本

const packageConfig = require('../package.json')

const shell = require('shelljs'卡塔尔国//shelljs 模块重新打包了 child_process,调用系统命令越发便民

function exec (cmd卡塔尔 {//重返通过child_process模块的新建子进度,实行 Unix 系统命令后转成未有空格的字符串

return require('child_process').execSync(cmd).toString().trim()

}

const versionRequirements = [

{

name: 'node',

currentVersion: semver.clean(process.version卡塔尔,//使用semver格式化版本

versionRequirement: packageConfig.engines.node //获取package.json中设置的node版本

}

]

if (shell.which('npm')) {

versionRequirements.push({

name: 'npm',

currentVersion: exec('npm --version'卡塔尔,// 自动调用npm --version命令,并且把参数再次回到给exec函数,进而拿到纯净的版本号

versionRequirement: packageConfig.engines.npm

})

}

module.exports = function () {

const warnings = []

for (let i = 0; i < versionRequirements.length; i ) {

const mod = versionRequirements[i]

//若版本号不相符package.json文件中钦定的版本号,就报错

if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {

warnings.push(mod.name ': '

chalk.red(mod.currentVersion) ' should be '

chalk.green(mod.versionRequirement)

)

}

}

if (warnings.length) {

console.log('')

console.log(chalk.yellow('To use this template, you must update following to modules:'))

console.log()

for (let i = 0; i < warnings.length; i ) {

const warning = warnings[i]

console.log(' ' warning)

}

console.log()

process.exit(1)

}

}

(3)utils.js:utils是工具的情致,是叁个用来管理css的公文,这几个文件包括了多个工具函数:

  • 变动静态能源的门路
  • 生成 ExtractTextPlugin对象或loader字符串
  • 生成 style-loader的配置

var path = require('path'卡塔尔(قطر‎// node自带的文书路线工具

var config = require('../config'卡塔尔// 配置文件

var ExtractTextPlugin = require('extract-text-webpack-plugin')// 提取css的插件

/** @method assertsPath 生成静态财富的门径(剖断开垦条件和生产条件,为config文件中index.js文件中定义assetsSubDirectory卡塔尔国

* @param {String} _path 相对于静态财富文件夹的公文路线

* @return {String} 静态能源全体路线

*/

exports.assetsPath = function (_path) {

var assetsSubDirectory = process.env.NODE_ENV === 'production'

? config.build.assetsSubDirectory

: config.dev.assetsSubDirectory

//nodeJs path提供用于拍卖文件路线的工具;path.posix提供对路径方法的POSIX(可移植性操作系统接口卡塔尔(قطر‎特定达成的探访(可跨平台卡塔尔(قطر‎; path.posix.join与path.join同样,不过一连以 posix 宽容的方法相互

return path.posix.join(assetsSubDirectory, _path)

}

/**@method cssLoaders 生成处理css的loaders配置,使用css-loader和postcssLoader,通过options.usePostCSS属性来决断是或不是选拔postcssLoader中回降等方式

* @param {Object} option = {sourceMap: true,// 是或不是展开sourceMapextract: true // 是或不是提取css}生成配置

* @return {Object} 管理css的loaders配置对象

*/

exports.cssLoaders = function (options) {

options = options || {}

var cssLoader = {

loader: 'css-loader',

options: {

minimize: process.env.NODE_ENV === 'production',

sourceMap: options.sourceMap

}

}

/**@method generateLoaders 生成 ExtractTextPlugin对象或loader字符串

* @param {Array} loaders loader名称数组

* @return {String|Object} ExtractTextPlugin对象或loader字符串

*/

function generateLoaders (loader, loaderOptions) {

var loaders = [cssLoader]

if (loader) {

loaders.push({

loader: loader '-loader',

options: Object.assign({}, loaderOptions, {

sourceMap: options.sourceMap

})

})

}

// ExtractTextPlugin提取css(当上边包车型大巴loaders未能正确引进时,使用vue-style-loader卡塔尔(英语:State of Qatar)

if (options.extract卡塔尔(英语:State of Qatar) {// 分娩条件中,默感到true

return ExtractTextPlugin.extract({

use: loaders,

fallback: 'vue-style-loader'

})

} else {//重返vue-style-loader连接loaders的尾声值

return ['vue-style-loader'].concat(loaders)

}

}

return {

css: generateLoaders(),//需要css-loader 和 vue-style-loader

postcss: generateLoaders(),//需要css-loader、postcssLoader 和 vue-style-loader

less: generateLoaders('less'),//需要less-loader 和 vue-style-loader

sass: generateLoaders('sass', { indentedSyntax: true }),//需要sass-loader 和 vue-style-loader

scss: generateLoaders('sass'),//需要sass-loader 和 vue-style-loader

stylus: generateLoaders('stylus'),//需要stylus-loader 和 vue-style-loader

styl: generateLoaders('stylus')//需要stylus-loader 和 vue-style-loader

}

}

/**@method styleLoaders 生成 style-loader的配置

* @param {Object} options 生成配置

* @return {Array} style-loader的配置

*/

exports.styleLoaders = function (options) {

var output = []

var loaders = exports.cssLoaders(options)

//将各个css,less,sass等汇总在联合具名得出结果输出output

for (var extension in loaders) {

var loader = loaders[extension]

output.push({

test: new RegExp('\.' extension '$'),

use: loader

})

}

return output

}

(4)vue-loader.conf.js:处理.vue文件,剖析那一个文件中的每一个语言块(template、、style卡塔尔,调换到js可用的js模块。

'use strict'

const utils = require('./utils')

const config = require('../config')

const isProduction = process.env.NODE_ENV === 'production'

//临蓐条件,提取css样式到独门文件

const sourceMapEnabled = isProduction

? config.build.productionSourceMap

: config.dev.cssSourceMap

module.exports = {

loaders: utils.cssLoaders({

sourceMap: sourceMapEnabled,

extract: isProduction

}),

cssSourceMap: sourceMapEnabled,

cacheBusting: config.dev.cacheBusting,

//编写翻译时将“引进路线”转变为require调用,使其可由webpack管理

transformToRequire: {

video: ['src', 'poster'],

source: 'src',

img: 'src',

image: 'xlink:href'

}

}

(5)webpack.base.conf.js:开拓、测验、分娩情形的国有根基配置文件,配置输出遭遇,配置模块resolve和插件等

'use strict'

const path = require('path'卡塔尔(英语:State of Qatar)// node自带的文本路线工具

const utils = require('./utils'卡塔尔(英语:State of Qatar)// 工具函数集合

const config = require('../config'卡塔尔(قطر‎// 配置文件

const vueLoaderConfig = require('./vue-loader.conf'卡塔尔// 工具函数集合

/**

* 获取"相对路线"

* @method resolve

* @param {String} dir 相对于本文件的门径

* @return {String} 相对路线

*/

function resolve(dir) {

return path.join(__dirname, '..', dir)

}

module.exports = {

context: path.resolve(__dirname, '../'),

//入口js文件(默感到单页面所以唯有app三个入口卡塔尔(قطر‎

entry: {

app: './src/main.js'

},

//配置出口

output: {

path: config.build.assetsRoot,//打包编写翻译的根路线(dist卡塔尔(英语:State of Qatar)

filename: '[name].js',

publicPath: process.env.NODE_ENV === 'production'

? config.build.assetsPublicPath

: config.dev.assetsPublic帕特h//发表路线

},

resolve: {

extensions: ['.js', '.vue', '.json'],// 自动补全的强大名

//小名配置

alias: {

'vue$': 'vue/dist/vue.esm.js',

'@': resolve('src'),// eg:"src/components" => "@/components"

}

},

module: {

rules: [

//使用vue-loader将vue文件编写翻译转变为js

{

test: /.vue$/,

loader: 'vue-loader',

options: vueLoaderConfig

},

//通过babel-loader将ES6编写翻译压缩成ES5

{

test: /.js$/,

loader: 'babel-loader',

include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]

},

//使用url-loader处理(图片、音像、字体),超过10000编译成

{

test: /.(png|jpe?g|gif|svg)(?.*)?$/,

loader: 'url-loader',

options: {

limit: 10000,

name: utils.assetsPath('img/[name].[hash:7].[ext]')

}

},

{

test: /.(mp4|webm|ogg|mp3|wav|flac|aac)(?.*)?$/,

loader: 'url-loader',

options: {

limit: 10000,

name: utils.assetsPath('media/[name].[hash:7].[ext]')

}

},

{

test: /.(woff2?|eot|ttf|otf)(?.*)?$/,

loader: 'url-loader',

options: {

limit: 10000,

name: utils.assetsPath('fonts/[name].[hash:7].[ext]')

}

}

]

},

//nodeJs全局变量/模块,防止webpack注入一些nodeJs的事物到vue中

node: {

setImmediate: false,

dgram: 'empty',

fs: 'empty',

net: 'empty',

tls: 'empty',

child_process: 'empty'

}

}

(6)webpack.dev.conf.js:webpack配置开拓条件中的入口

'use strict'

const utils = require('./utils')

const webpack = require('webpack')

const config = require('../config')

const merge = require('webpack-merge'卡塔尔(قطر‎//webpack-merge实现归并

const path = require('path')

const baseWebpackConfig = require('./webpack.base.conf')

const CopyWebpackPlugin = require('copy-webpack-plugin')

const HtmlWebpackPlugin = require('html-webpack-plugin')

const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin'卡塔尔//webpack的唤起错误和日志音信的插件

const portfinder = require('portfinder'卡塔尔(قطر‎// 查看空闲端口地点,暗许情形下搜寻8000以此端口

const HOST = process.env.HOST

const PORT = process.env.PORT && Number(process.env.PORT)

const devWebpackConfig = merge(baseWebpackConfig, {

module: {

rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true })

},

devtool: config.dev.devtool,//调节和测量试验形式

devServer: {

clientLogLevel: 'warning',

historyApiFallback: {//使用 HTML5 History API 时, 404 响应代替为 index.html

rewrites: [

{ from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') },

],

},

hot: true,//热重载

contentBase: false, // 提供静态文件访谈

compress: true,//压缩

host: HOST || config.dev.host,

port: PORT || config.dev.port,

open: config.dev.autoOpenBrowser,//npm run dev 时自动展开浏览器

overlay: config.dev.errorOverlay

? { warnings: false, errors: true }

: false,// 显示warning 和 error 信息

publicPath: config.dev.assetsPublicPath,

proxy: config.dev.proxyTable,//api代理

quiet: true, //调整台打字与印刷警报和谬误(用FriendlyErrorsPlugin 为 true卡塔尔

watchOptions: {// 检查评定文件改变

poll: config.dev.poll,

}

},

plugins: [

new webpack.DefinePlugin({

'process.env': require('../config/dev.env')

}),

new webpack.HotModuleReplacementPlugin(卡塔尔(قطر‎,//模块热替换插件,改良模块时无需刷新页面

new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update.

new webpack.NoEmitsPlugin(卡塔尔,//webpack编写翻译错误的时候,中断打包进度,幸免错误代码打包到文件中

// 将包裹编写翻译好的代码插入index.html

new HtmlWebpackPlugin({

filename: 'index.html',

template: 'index.html',

inject: true

}),

// 提取static assets 中css 复制到dist/static文件

new CopyWebpackPlugin([

{

from: path.resolve(__dirname, '../static'),

to: config.dev.assetsSubDirectory,

ignore: ['.*']//忽略.*的文件

}

])

]

})

module.exports = new Promise((resolve, reject) => {

portfinder.basePort = process.env.PORT || config.dev.port

portfinder.getPort((err, port卡塔尔(英语:State of Qatar) => { //查找端口号

if (err) {

reject(err)

} else {

//端口被攻克时就再一次安装evn和devServer的端口

process.env.PORT = port

devWebpackConfig.devServer.port = port

// npm run dev成功的情分提醒

devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({

compilationSuccessInfo: {

messages: [`Your application is running here: ],

},

s: config.dev.notifys

? utils.createNotifierCallback()

: undefined

}))

resolve(devWebpackConfig)

}

})

})

(7)webpack.dev.prod.js:webpack配置生产意况中的入口

'use strict'

const path = require('path')

const utils = require('./utils')

const webpack = require('webpack')

const config = require('../config')

const merge = require('webpack-merge')

const baseWebpackConfig = require('./webpack.base.conf')

const CopyWebpackPlugin = require('copy-webpack-plugin')

const HtmlWebpackPlugin = require('html-webpack-plugin')

const ExtractTextPlugin = require('extract-text-webpack-plugin')

const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')

const UglifyJsPlugin = require('uglifyjs-webpack-plugin')

const env = require('../config/prod.env')

const webpackConfig = merge(baseWebpackConfig, {

module: {

rules: utils.styleLoaders({

sourceMap: config.build.productionSourceMap,

extract: true,

usePostCSS: true

})

},

devtool: config.build.productionSourceMap ? config.build.devtool : false,//是或不是展开调节和测验格局

output: {

path: config.build.assetsRoot,

filename: utils.assetsPath('js/[name].[chunkhash].js'),

chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')

},

plugins: [

new webpack.DefinePlugin({

'process.env': env

}),

new UglifyJsPlugin({//压缩js

uglifyOptions: {

compress: {

warnings: false

}

},

sourceMap: config.build.productionSourceMap,

parallel: true

}),

new ExtractTextPlugin({//提取静态文件,裁减央浼

filename: utils.assetsPath('css/[name].[contenthash].css'),

allChunks: true,

}),

new OptimizeCSSPlugin({//提取优化压缩后(删除来自不一样组件的冗余代码卡塔尔国的css

cssProcessorOptions: config.build.productionSourceMap

? { safe: true, map: { inline: false } }

: { safe: true }

}),

new HtmlWebpackPlugin({ //html打包压缩到index.html

filename: config.build.index,

template: 'index.html',

inject: true,

minify: {

removeComments: true,//删除注释

collapseWhitespace: true,//删除空格

removeAttributeQuotes: true//删除属性的引号

},

chunksSortMode: 'dependency'//模块排序,遵照大家要求的次第排序

}),

new webpack.HashedModuleIdsPlugin(),

new webpack.optimize.ModuleConcatenationPlugin(),

new webpack.optimize.CommonsChunkPlugin({ // node_modules中的任何所需模块都领到到vendor

name: 'vendor',

minChunks (module) {

return (

module.resource &&

/.js$/.test(module.resource) &&

module.resource.indexOf(

path.join(__dirname, '../node_modules')

) === 0

)

}

}),

new webpack.optimize.CommonsChunkPlugin({

name: 'manifest',

minChunks: Infinity

}),

new webpack.optimize.CommonsChunkPlugin({

name: 'app',

async: 'vendor-async',

children: true,

minChunks: 3

}),

new CopyWebpackPlugin([//复制static中的静态财富(暗许到dist里面)

{

from: path.resolve(__dirname, '../static'),

to: config.build.assetsSubDirectory,

ignore: ['.*']

}

])

]

})

if (config.build.productionGzip) {

const CompressionWebpackPlugin = require('compression-webpack-plugin')

webpackConfig.plugins.push(

new CompressionWebpackPlugin({

asset: '[path].gz[query]',

algorithm: 'gzip',

test: new RegExp(

'\.('

config.build.productionGzipExtensions.join('|')

')$'

),

threshold: 10240,

minRatio: 0.8

})

)

}

if (config.build.bundleAnalyzerReport) {

const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin

webpackConfig.plugins.push(new BundleAnalyzerPlugin())

}

module.exports = webpackConfig

2、config文件夹:

config文件夹的组织:

图片 5

(1) dev.env.js和prod.env.js:分别配备:开拓遭遇和生育景况。这一个能够依靠集团事情构成后端须要陈设须要区分开荒条件和测量检验景况的习性

'use strict'

const merge = require('webpack-merge')

const prodEnv = require('./prod.env')

module.exports = merge(prodEnv, {

NODE_ENV: '"development"'

})

ps:webpack-merge用于完毕合并相符于ES6的Object.assign(卡塔尔(قطر‎

'use strict'

module.exports = {

NODE_ENV: '"production"'

}

(*只顾属性值要用“‘’”双层引住),访谈(获取值)时一贯用:

process.env.属性名

ps:process(进度)是nodejs的叁个全局变量,process.env 属性重回多少个顾客蒙受消息的目的

(2)index.js配置剖析:

'use strict';

const path = require('path');

module.exports = {

// ===================开辟条件铺排

dev: {

assetsSubDirectory: 'static',//静态能源文件夹(日常寄存css、js、image等公事卡塔尔(英语:State of Qatar)

assetsPublicPath: '/',//根目录

proxyTable: {},//配置API代理,可利用该属性扫除跨域的标题

host: 'localhost', // 可以被 process.env.HOST 覆盖

port: 3030, // 可以被 process.env.PORT 覆盖

autoOpenBrowser: true,//编写翻译后活动张开浏览器页面 host",暗许"false"卡塔尔,设置路由重定向自动展开你的默许页面

errorOverlay: true,//浏览器错误提醒

notifys: true,//跨平台错误提示

poll: false, //webpack提供的施用文件系统(file system卡塔尔国获取文件改换的打招呼devServer.watchOptions(监察和控制文件改造卡塔尔(英语:State of Qatar)

devtool: 'cheap-module-eval-source-map',//webpack提供的用来调解的格局,有三个差别值代表不一致的调节和测量试验形式

cacheBusting: true,// 合营devtool的安顿,当给文件名插入新的hash招致解除缓存时是或不是生成source-map

cssSourceMap: true //记录代码压缩前的岗位消息,当发生错误时一贯定位到未压缩前的职位,方便调节和测验

},

// ========================生产意况布署

build: {

index: path.resolve(__dirname, '../dist/index.html'卡塔尔国,//编写翻译后"首页面"生成的相对路线和名字

assetsRoot: path.resolve(__dirname, '../dist'卡塔尔(英语:State of Qatar),//打包编写翻译的根路线(默许dist,存放打包压缩后的代码卡塔尔国

assetsSubDirectory: 'static',//静态能源文件夹(平时存放css、js、image等文件卡塔尔(英语:State of Qatar)

assetsPublicPath: '/',//宣布的根目录(dist文件夹所在门路卡塔尔国

productionSourceMap: true,//是或不是开启source-map

devtool: '#source-map',//(详细参见:)

productionGzip: false,//是还是不是减弱

productionGzipExtensions: ['js', 'css'],//unit的gzip命令用来压缩文件(gzip形式下供给减弱的文件的增加名有js和css)

bundleAnalyzerReport: process.env.npm_config_report //是不是开启包装后的分析报告

}

};

3、node_modules文件夹:寄放npm install时依据package.json配置生成的npm安装包的公文夹

4、src文件夹:我们需求在src文件夹中费用代码,打包时webpack会依照build中的准则(build法规信赖于config中的配置)将src打包压缩到dist文件夹在浏览器中运作

(1)assets文件:用于贮存静态财富(css、image),assets打包时路线会经过webpack中的file-loader编写翻译(因而,assets要求接纳相对路线)成js

(2)components文件夹:用来存放在 .vue 组件(完毕复用等作用,如:过滤器,列表项等卡塔尔(英语:State of Qatar)

(3)router文件夹:在router/index.js文件中配置页面路由

(4)App.vue:是整整项指标主组件,全体页面都是透过采纳<router-view/>开放入口在App.vue下举行切换的(全部的路由都是App.vue的子组件)

(5)main.js:入口js文件(全局js,你能够在那间:开端化vue实例、require/import需求的插件、注入router路由、引进store状态管理)

5、static文件夹:webpack私下认可存放静态文件(css、image)的文件夹,与assets不相同的是:static在卷入时会直接复制一个同名文件夹到dist文件夹里(不会透过编写翻译,可采纳相对路线)

6、其余文件:

(1).babelrc:浏览器剖析的相称配置,该文件重大是对预设(presets)和插件(plugins)进行安顿,由此差异的转译器功效不一致的配置项,大约可分为:语法转义器、补丁转义器、sx和flow插件

(2).editorconfig:用于配置代码格式(合营代码检查工具使用,如:ESLint,共青团和少先队开荒时可统一代码风格),这里配置的代码标准准则优先级高于编辑器暗中认可的代码格式化准绳。

(3).gitignore:配置git提交时须要忽视的公文

(4)postcssrc.js: autoprefixer(自动补全css样式的浏览器前缀);postcss-import(@import引进语法)、CSS Modules(规定样式功效域)

(5)index.html:项目入口页面,编写翻译之后有所代码将插入到那来

(6)package.json:npm的安插文件(npm install依据package.json下载对应版本的安装包)

(7)package.lock.json:npm install(安装)时锁定各包的版本号

(8)README.md:项目采纳验证

1、传统:

<script src=“module.js”>标签;


前言

本身直接感到模仿和借鉴是上学三个新东西最高效的情势。所以自个儿建议仍然经过借鉴一些老奸巨猾的 webpack 配置相比好。举例你项目是基于 react 生态圈的话能够借鉴 create-react-app ,下载之后npm run eject 就足以看来它详细的 webpack 配置了。vue 的话由于新版vue cli不支持 eject了,并且改用 webpack-chain来配置,所以借鉴起来只怕会不太有利,主要构造 地址。感到麻烦的话你能够平素借鉴 vue-element-admin 的 配置。恐怕您想和煦发挥,你能够借鉴 webpack 官方的各样 examples,来构成你的布署。

五、运维项目

在webStorm中开发项目,首先赶紧右击Project进行如下操作(不然会卡死,还会有各类其余形式参见:

图片 6

(1)运营安装:cnpm install

图片 7

(2)然后npm run dev:跑起来~

图片 8

(3)生成打包文件 :npm run build

然后您会意识项目多了个dist文件夹(用于铺排到生育条件用,是包装压缩之后的src文件夹)

图片 9

© 作品权归小编全数再次回到微博,查看更加多

主要编辑:

2、commonJS:

一路require()同步加载,再通过exports或module.exports来导出须要暴露的接口;无法加载多少个模块;不契合浏览器加载。

我们项指标框架使用的是angular.js(v1.5.8) webpack,使用webpack首借使要想做到以下几点:
1.遗弃原本项目中的requireJs,gulp/grunt。模块化和包裹均由webpack实现。
2.将品种能源大部分出口到二个bundle.js文件,收缩浏览器第三回加载时的财富恳求数量。
3.行使npm安装框架重视。不再引进项目中。防止项目代码提交时纠正库代码。
4.张开代码压缩,并开启nginx的gzip,对代码再次进行压缩。
5.完成测验和坐褥条件使用不一样的配备文件。
6.生成带有项目名称和本子号的文书夹并削减(用于webApp卡塔尔(英语:State of Qatar)。
7.生成带有hash的bundle.js文件。能够减轻浏览器因为缓存不刷新的主题材料(用于web项目卡塔尔(英语:State of Qatar)。

因为品种情形,没有用到es6,scss等。没有实行代码转换。要是急需转码,只要找到呼应的loader。npm安装后加载进来就足以了,这里不会提到。其余,webpack笔者也没用多长期。假使哪个地方写的不佳也许写错了,请教导,多谢!
先奉上webpack文书档案地址:webpack

升级 webpack

先是将 webpack 进级到 4 之后,直接运营webpack --xxx是格外的,因为新本子将命令行相关的事物单独拆了出去封装成了webpack-cli。会报如下错误:

The CLI moved into a separate package: webpack-cli.
Please install webpack-cli in addition to webpack itself to use the CLI.

持有你必要安装npm install webpack-cli -D -S。你也可将它安装在大局。

同有的时候间新版 webpack 要求Node.js 的最低支持版本为 6.11.5决不要忘了进步。要是还供给保养老项目得以接收 nvm 来做一下 node 版本管理。

进级具备信任

因为webpack4改了 它的hook api ,所以具备的loadersplugins都亟待提高能力够适配。

能够利用命令行 npm outdated,列出所以能够立异的包。免得一再个个去npm找相对于的可用版本了。

图片 10

反正把devDependencies的依靠都进级一下,总归不会有错。

3、AMD:

异步require,通过接口define() 异步加载;可互相加载五个模块;符合浏览器。


带给的变通

实际上此番进级带给了相当多改成,但大比非常多其实对于普通客户来讲是无需关怀的,比方此次进级带给的功能SideEffectsModule Type’s IntroducedWebAssembly Support,基本平常是用不到的。我们最主要关怀那个对大家影响相当的大的转移如:optimization.splitChunks替代它本来的CommonsChunkPlugin(下篇小说会爱戴介绍卡塔尔(قطر‎,和Better Defaults-mode更加好的暗中同意配置,那是权族不怎么要求关心一下的。

图片 11

要是想进一层了然 Tree ShakingSideEffects的可以见到文末扩充阅读。
上海体育场所参谋 Webpack 4 进阶

4、CMD:

类似AMD;

▍第一步:搭建际遇

暗许配置

webpack 4 引入了零配置的概念,被 parcel 刺激到了。 不管效果如何,那改换只怕值得陈赞的。

这几天又新出了 Fastpack 能够关心一下。

言归正题,大家来拜望 webpack 暗许帮我们做了些什么?

development 情势下,暗许开启了NamedChunksPluginNamedModulesPlugin有利调节和测量试验,提供了更完整的错误音讯,越来越快的双重编写翻译的进程。

module.exports = { mode: 'development' - devtool: 'eval', - plugins: [ - new webpack.NamedModulesPlugin(), - new webpack.NamedChunksPlugin(), - new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("development") }), - ] }

1
2
3
4
5
6
7
8
9
module.exports = {
mode: 'development'
- devtool: 'eval',
- plugins: [
-   new webpack.NamedModulesPlugin(),
-   new webpack.NamedChunksPlugin(),
-   new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("development") }),
- ]
}

production 形式下,由于提供了splitChunksminimize,所以基本零配置,代码就能活动分割、压缩、优化,同时webpack 也会自动帮你 Scope hoistingTree-shaking

module.exports = { mode: 'production', - plugins: [ - new UglifyJsPlugin(/* ... */), - new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("production") }), - new webpack.optimize.ModuleConcatenationPlugin(), - new webpack.NoEmitOnErrorsPlugin() - ] }

1
2
3
4
5
6
7
8
9
module.exports = {
  mode: 'production',
-  plugins: [
-    new UglifyJsPlugin(/* ... */),
-    new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("production") }),
-    new webpack.optimize.ModuleConcatenationPlugin(),
-    new webpack.NoEmitOnErrorsPlugin()
-  ]
}

webpack 长期以来最深受诟病的便是其配置门槛相当高,配置内容极度复杂和麻烦,轻易令人从入门到扬弃,而它的新锐如 rollup、parcel 等均在布署流程上做了宏大的优化,做到开箱即用,所以webpack 4 也从当中借鉴了过多种经营历来升高自己的配置作用。愿俗尘再也没有供给 webpack 配置程序猿

5、UMD:

是模块跨平台施工方案;

安装node.js和npm

npm 是 javaScript的包处理工科具,相仿maven的重视管理, 用它来下载我们要求的模块。
Node.js下载地址

html-webpack-plugin

用前卫版本的的 html-webpack-plugin您大概还有可能会赶过如下的大谬否则:

throw new Error('Cyclic dependency' nodeRep)

发出那么些 bug 的从头到尾的经过是循环引用正视,倘若你未曾那个标题得以忽视。

当下应用方案能够利用 Alpha 版本,npm i --save-dev html-webpack-plugin@next

可能参与chunksSortMode: 'none'就能够了。

但留神翻看文书档案件发生掘设置成chunksSortMode: 'none'这么是会不正常的。

Allows to control how chunks should be sorted before they are included to the HTML.

那属性会决定你 chunks 的加载顺序,要是设置为none,你的 chunk 加载在页面中加载的顺序就不可见确认保证了,恐怕会并发样式被掩没的事态。举例本人在app.css个中期维修改了一个第三方库element-ui的体裁,通过加载顺序的前后相继来掩瞒它,但出于设置为了none,打包出来的结果形成了如此:

<link href="/app.8945fbfc.css" rel="stylesheet"> <link href="/chunk-elementUI.2db88087.css" rel="stylesheet">

1
2
<link href="/app.8945fbfc.css" rel="stylesheet">
<link href="/chunk-elementUI.2db88087.css" rel="stylesheet">

app.css被先加载了,此前写的体制覆盖就失效了,除非你使用important抑或此外css 权重的方式覆盖它,但那肯定是不太合理的。
vue-cli无独有偶也许有其一相关 issue,尤雨溪也在不选择@next本子的底蕴上 hack 了它,风野趣的能够自身商讨一下,自己在类型中央直属机关接采取了@next本子,也没遇上其余什么难点(除了不相称webpack 的 prefetch/preload 相关 issue)。三种方案都能够,自行选拔。

其它 html-webpack-plugin 的安顿和事情发生前运用未有啥分别。

6、ES6:

尽只怕静态化;编写翻译时就能够分明模块的借助关系及输入输出变量;CommonJs和英特尔都只好在运转时规定这么些东西。
可取:静态深入分析,提前编写翻译;面向现在的正规化;
缺点:
1、浏览器原生包容性差,所以日常都编写翻译成ES5。
2、近年来得以拿来即用的模块少,生态差。

创建package.json

npm init
在品种文件夹下新建四个package.json并填写项目音信,项目名称以致版本号等连串消息

mini-css-extract-plugin

7、期待的模块:

可以合作三种模块风格,尽量能够动用原来就有的代码,不止只是 JavaScript 模块化,还应该有 CSS、图片、字体等能源也须求模块化。

npm安装插件

大局安装webpack:
npm install webpack -g
安装webpack-dev-server:
npm install webpack-dev-server -g
设置信任到品种中并参预package.json
npm install [package] --save-dev/ npm install [package] --save
莫不一时候会npm安装包异常的慢以至是设置不了,能够选取TmallNPM镜像[cnpm]
去除信任
npm uninstall [package]

与 extract-text-webpack-plugin 区别

由于webpack4对 css 模块协理的精细入微以至在处理 css 文件提取的办法上也做了些调治,所今后边大家一向利用的extract-text-webpack-plugin也旗开马到了它的历史义务,将让坐落于mini-css-extract-plugin

应用办法也很简短,大家望着 文档 抄就足以了。

它与extract-text-webpack-plugin最大的分别是:它在code spliting的时候会将本来内联写在每二个js chunk bundle的 css,单独拆成了一个个 css 文件。

原来 css 是如此内联在 js 文件里的:
图片 12

将 css 独立拆包最大的收益正是 js 和 css 的变动,不会潜移暗化对方。比方笔者改了 js 文件并不会导致 css 文件的缓存失效。何况今后它自动会合营optimization.splitChunks的计划,能够自定义拆分 css 文件,举个例子作者独立安插了element-ui作为独立八个bundle,它会活动也将它的体制单独打包成叁个css 文件,不会像从前暗中认可将第三方的 css 全体打包成叁个几十居然上百 KB 的app.xxx.css文件了。

图片 13

二、gulp&webpack区别:

gulp是基于流的构建筑工程具:all in one的打包格局,输出多个js文件和三个css文件,优点是压缩http央求,万金油方案。
webpack是模块化管理工科具,使用webpack能够对模块举办减削、预管理、打包、按需加载等。

▍第二步:编写webpack.config.js文件

裁减与优化

打包 css 之后查看源码,大家开采它并未帮大家做代码压缩,这时需求选拔 optimize-css-assets-webpack-plugin 那一个插件,它不仅能帮你降低 css 还可以优化你的代码。

//配置 optimization: { minimizer: [new OptimizeCSSAssetsPlugin()]; }

1
2
3
4
//配置
optimization: {
  minimizer: [new OptimizeCSSAssetsPlugin()];
}

图片 14

如上航海用体育场合测量试验用例所示,由于optimize-css-assets-webpack-plugin其黄金年代插件暗许使用了 cssnano 来作 css 优化,
于是它不光收缩了代码、删掉了代码中没用的评释、还去除了冗余的 css、优化了 css 的书写顺序,优化了你的代码 margin: 10px 20px 10px 20px; =>margin:10px 20px;。同期大大减小了您 css 的文件大小。越来越多优化的细节见文档。

三、webpack概念:

webpack是模块化管理工科具,使用webpack可以对模块实行压缩、预管理、按需打包、按需加载等。

代码:webpack anuglar.js

contenthash

但使用 MiniCssExtractPlugin 有叁个必要极度注意的地点,在暗中认可文书档案中它是这么安顿的:

new MiniCssExtractPlugin({ // Options similar to the same options in webpackOptions.output // both options are optional filename: devMode ? "[name].css" : "[name].[hash].css", chunkFilename: devMode ? "[id].css" : "[id].[hash].css" });

1
2
3
4
5
6
new MiniCssExtractPlugin({
  // Options similar to the same options in webpackOptions.output
  // both options are optional
  filename: devMode ? "[name].css" : "[name].[hash].css",
  chunkFilename: devMode ? "[id].css" : "[id].[hash].css"
});

差相当的少说多美滋(Dumex卡塔尔国(Nutrilon卡塔尔国下: filename 是指在你输入文件entry中引进生成出来的文书名,而chunkname是指那多少个未被在入口文件entry引进,但又经过按需加载(异步)模块的时候引进的文件。

copy 如上代码应用现在开掘景况不对!每趟改变一个xx.js文件,它对应的 css 纵然没做此外更改,但它的 文件 hash 依然会爆发变化。留心相比较开采原本是 hash 惹的祸。 6.f3bfa3af.css => 6.40bc56f6.css

图片 15

但自身那是依据官方文书档案来写的!为何还不正常!后来在文书档案的最最最下边发下了那样生龙活虎段话!

For long term caching use filename: [contenthash].css. Optionally add [name].

这几个的不精通,这么重大的一句话会放在 Maintainers 还后边的地点,私下认可写在布置内部提醒我们不是越来越好?有热情公众现已开了叁个pr,将文书档案暗中认可配置为 contenthashchunkhash => contenthash相关 issue。

本条真的蛮过分的,稍不注意就能够让协调的 css 文件缓存无效。何况不少客商日常涂改代码的时候都不会留意友好最终包装出来的 dist文本夹中到底有何变化。所以那一个标题只怕就径直留存了。浪费了不怎么财富!人艰不拆!大家以为webpack 难用不是没道理的。

四、webpack9个特征:

(1)插件化:webpack本人特别灵活,提供了丰硕的插件接口。基于这几个接口,webpack开辟了众多插件作为内置效率。
(2)速度快:webpack使用异步IO甚至生机勃勃种类缓存机制。所以webpack的过程是高速的,越发是增量更新。
(3)丰盛的Loaders:loaders用来对文件做预管理。那样webpack就足以打包任王喜乐态文件。
(4)高适配性:webpack同一时间支持Intel/CommonJs/ES6模块方案。webpack会静态深入分析你的代码,自动帮您管理他们的依赖性关系。此外,webpack对第三方库的包容性很好。
(5)代码拆分:webpack能够将您的代码分片,进而完结按需打包。这种机制得以确认保证页面只加载须求的JS代码,收缩第二次呼吁的时日。
(6)优化:webpack提供了好些个优化学工业机械制来压缩打包输出的文件大小,不唯有如此,它还提供了hash机制,来减轻浏览器缓慰劳题。
(7)开采方式友好:webpack为付出形式也提供了无数帮扶成效。譬喻SourceMap、热更新等。
(8)使用情况多:webpack不止适用于web应用途景,也适用于Webworkers、Node.js场景。
(9)优点:webpack并不强制你接纳某种模块化方案,而是通过相配全数模块化方案让您无痛接入项目,当然那也是webpack牛逼的地点。
有了webpack,你能够私自筛选你赏识的模块化方案,至于怎么管理模块之间的信赖关系及怎么样按需打包,放轻便,webpack会帮您管理好的。

目录布局:
webpack
|____app
| |____index.html
| |____index.js
|____package.json
|____webpack.config.js
|____zip.js

此间再不难说美赞臣(Meadjohnson卡塔尔国(Karicare卡塔尔国下三种 hash 的界别:

  • hash

hash 和每次 build关于,未有其他变动的图景下,每一趟编写翻译出来的 hash都以如出意气风发辙的,但当你转移了任何一点东西,它的hash就能够产生变动。

简易明白,你改了此外东西,hash 就能和上次不均等了。

  • chunkhash

chunkhash是依赖现实每三个模块文件自身的的源委囊括它的依赖性计算机才能钻探所得的hash,所以有些文件的改观只会潜移暗化它本人的hash,不会耳熏目染别的文件。

  • contenthash

它的面世根本是为着缓和,让css文件不受js文件的影响。比方foo.cssfoo.js引用了,所以它们共用平等的chunkhash值。但这样子是有标题标,假使foo.js更正了代码,css文件即使内容并未其余改造,由于是该模块的 hash 发生了改换,其css文件的hash也会跟着转移。

这时大家就足以行使contenthash了,保险纵然css文本所处的模块里有别的内容的改换,只要 css 文件内容不改变,那么它的hash就不会产生变化。

contenthash 你能够简轻易单明白为是 moduleId content 所生成的 hash

五、webpack配置及参数深入剖析:

1、两份配置文件webpack.config.production.js/webpack.config.development.js,然后差异情形下,使用不相同的布署文件。
2、通过module.exports重返函数,该函数能接纳参数。
相对来讲,第生机勃勃种更轻巧,可是再一次配置多;第两种越来越灵敏,推荐第三种艺术。

运用loader加载器对财富扩充转移
module.exports = {
    entry: path.resolve(__dirname, "app", "index.js"),
    output: {
        path: "dist",
        filename: "bundle.[hash].js"
    },
    module: {
        loaders: [
            {
               test: /.js$/,
               exclude: /node_modules/,
                loader:"ng-annotate"
            }, {
               test: /.css$/,
               loader: "style!css!autoprefixer"
            }, {
               test: /.html$/,  
               exclude: /node_modules/,
               loader:"html"
            }, {
               test: /.(ttf|eot|otf)$/,
               loader: "file"
            }, {
               test: /.woff(2)?$/,
               loader: "url?limit=8192&minetype=application/font-woff"
            }, {
               test: /.(png|jpg|gif|svg)$/,
               loader: "url?limit=8192&name=images/[name].[ext]"
            }
        ]
    }
}

热更新速度

实在相对 webpack 线上包裹速度,作者更关爱的地头开辟热更新速度,毕竟那才是和我们每多个程序员每一日真正打交道的事物,打包平时都会扔给CI自动施行,而且平常品种天天也不会卷入很频仍。

webpack 4一向说自身更加好的采纳了cache压实了编写翻译速度,但实测发掘是有确定的晋级换代,但当你二个门类,路由懒加载的页面多了现在,50 之后,热更新慢的主题素材会很鲜明,早先的文章中也关乎过这么些标题,原认为新版本会消除这一个难点,但并未。

可是你首先要排挤你的热更新慢不是,如:

  • 并未有利用合理的 Devtool souce map 导致
  • 一直不允许确接受 exclude/include 管理了无需管理的如node_modules
  • 在付出条件不要压缩代码UglifyJs、提取 css、babel polyfill、总括文件 hash 等无需的操作

旧方案

最初的方案是开荒蒙受中不是用路由懒加载了,只在线上意况中应用。封装一个_import函数,通过情况变区分是或不是需求懒加载。

开采条件:

module.exports = file => require("@/views/" file ".vue").default;

1
module.exports = file => require("@/views/" file ".vue").default;

转变情况:

module.exports = file => () => import("@/views/" file ".vue");

1
module.exports = file => () => import("@/views/" file ".vue");

但由于 webpack import落到实处机制难题,会发出一定的副功效。如上边的写法就能够导致@/views/下的 所有.vue 文件都会被包裹。不管您是不是被信赖援用了,会多打包一些可能长久都用不到 js 代码。 相关 issue

日前新的解决方案思路依然长久以来的,只在转换方式中使用路由懒加载,当地开辟不利用懒加载。但换了后生可畏种没副作用的兑现方式。

新方案

使用babelplugins babel-plugin-dynamic-import-node。它只做黄金年代件事正是:将有所的import()转化为require(),那样就能够用那个插件将具有异步组件都用联合的法子引进了,并结合 BABEL_ENV 这个bebel境况变量,让它只遵循于付出遭遇下。将付出意况中具备import()转化为require(),这种方案驱除了后面再一次打包的主题素材,同偶尔间对代码的侵入性也超级小,你平时写路由的时候只必要固守官方文档路由懒加载的主意就能够了,别的的都交给babel来处理,当您不想用那些方案的时候,也只须要将它从babelplugins中移除就足以了。

切实代码:

首先在package.json中增加BABEL_ENV

"dev": "BABEL_ENV=development webpack-dev-server XXXX"

1
"dev": "BABEL_ENV=development webpack-dev-server XXXX"

接着在.babelrc只好加盟babel-plugin-dynamic-import-node这个plugins,并让它唯有在development形式中才生效。

{ "env": { "development": { "plugins": ["dynamic-import-node"] } } }

1
2
3
4
5
6
7
{
  "env": {
    "development": {
      "plugins": ["dynamic-import-node"]
    }
  }
}

之后就瓜熟蒂落了,路由只要像平时相似写就能够了。文档

{ path: '/login', component: () => import('@/views/login/index')}

1
{ path: '/login', component: () => import('@/views/login/index')}

那样能大大进步你热更新的快慢。基本三百加页面也能在2000ms的热跟新产生,基本做到无感刷新。当然你的类型本人就相当小页面也不多,完全没有必要搞这么些。当您的页面变化跟不是你写代码速度的时候再思考也不迟。

webpack 怎么着最好配置?

webpack官方提供的安顿格局是经过module.exports重临二个json,可是这种光景不灵便,不可能适配多种场景。举个例子要清除:production方式和development情势,webpack的配备是差异的,大约有二种思路。
1、两份配置文件webpack.config.production.js/webpack.config.development.js
,然后不相同场景下,使用分化的安排文件。
2、通过module.exports重返函数,该函数能选用参数。
相对来讲,第生龙活虎种更简约,不过再度配置多;第三种更加灵活,推荐第三种办法。那么,按重返函数的方法的配备代码架子如下:

module.exports = function(env) {
return { context: config.context,
entry: config.src, output: { path: path.join(config.jsDest, project),
filename: '[name].js',
chunkFilename: '[name].[chunkhash:8].js', publicPath: '/assets/' project '/'
},
devtool: "eval", watch: false, profile: true, cache: true, module: {
loaders: getLoaders(env)
},
resolve: {
alias: getAlias(env)
},
plugins: getPlugins(env)
};
}

entry编写翻译的入口Js文件。ouput文本输出定义

编写翻译后的文本名bundle.[hash].js,这里运用hash。每三回开展webpack打包,都会生成三个hash值,用它为文件命名,能让每一趟更改的文书名都不相同等。浏览器访谈也不会存在缓慰劳题。path.resolve用来拼接路线,__dirname是指当前路径的相对路线。

装进速度

webpack 4 在档期的顺序中其实地度量了下,广泛能巩固 75%~33.33%的打包速度。

正文不筹算太深入的上书这有的内容,详细的打包优化速度能够参考slack 团队的那篇小说,掘金队还会有译文.

那边有几个提议来帮您加快 webpack 的打包速度。

第后生可畏你须求通晓您眼下打包慢,是慢在何地。

作者们能够用 speed-measure-webpack-plugin 那个插件,它能监察和控制 webpack 每一步操作的耗费时间。如下图:

图片 16

能够看出其实抢先二分之一装进开支的时间是在Uglifyjs调减代码。和近期的进级换代热更新的切入点大约,查看source map的科学与否,exclude/include的不易采纳等等。

选用新版的UglifyJsPlugin的时候记住能够增加cache: trueparall: true,能够提搞代码打包压缩速度。越多配备能够参照他事他说加以考察 文档 或者 vue-cli 的 配置。

编写翻译的时候还大概有还应该有三个一点也不快的由来是那多少个第三方库。比方echartselement-ui实际都十分的大,举个例子echarts包装完也还会有775kb。所以您想大大进步编写翻译速度,能够将那个第三方库 externals 出去,使用script的措施引进,也许应用 dll的格局打包。经测验平日如echarts像这种类型大的包能够节约十几秒到几十秒不等。

再有能够选拔部分并行实施 webpack 的库:如parallel-webpack、happypack。

顺手说一下,晋级一下node想必有悲喜。明日将CI当中的 node 版本正视从 6.9.2 => 8.11.3,打包速度一向提高了一分多钟。

总的说来小编认为打包时间决定在大概的限制内就足以了,没须要过于的优化。大概你商讨了半天,改了一群参数发掘其实也就晋级了几秒,但保卫安全资金上去了,事倍功半。还比不上进级node、进级 webpack、晋级你的编写翻译碰到的硬件水平来的实在和总结。

举例说小编司CI应用的是Tencent云普通的的 8 核 16g 的机械,这么些类别也是三个超级大的后台管理项目 200 页面,援用了大多第三方的库,但尚无接收什么happypackdll,只是用了新星版的webpack4node@8.11.3
编写翻译速度平稳在三分多钟,完全不以为有啥要优化的尤为重要。

图片 17

其间第生机勃勃的布置那儿简要介绍如下:

context:上下文。
entry:入口文件,是装有看重关系的输入,webpack从那几个进口带头静态拆解解析,剖析模块之间的依赖关系。
output:打包输出的布署。
devtools:SourceMap选项,便于开荒方式下调节和测量检验。
watch:监听格局,增量更新,开拓必备!
profile:优化。
cache:webpack构建的历程中会生成超多有的时候的文件,张开cache能够让这么些临时的文书缓存起来,进而越来越快的营造。
module.loaders:如前文介绍,loaders用来对文件做预管理。那样webpack就足以打包任王健态文件。
resolve.alias:模块小名,这样能够更实惠的援引模块。
plugins:如前文介绍,webpack的有的置于效能均是以插件的款型提供。

loader加载器的运用,如css-loader。

先是安装css-loader:npm install --save-dev css-loader
在配备文件中,通过正则绑定对应的loader, 能够归纳loader,写成css/css-loader均可。使用!能够定义多个loader,?末尾配置参数

Tree-Shaking

那实际并不是 webpack 4 才提出来的概念,最先是 rollup 建议来并落到实处的,后来在 webpack 2 中就贯彻了,此次在 webpack 4 只是增加了 JSON Tree ShakingsideEffects能令你能越来越好的

可是这里照旧要提一下,私下认可 webpack 是支持Tree-Shaking的,但在你的品种中大概会因为babel的来由产生它失效。

因为Tree Shaking其一职能是基于ES6 modules 的静态性子检查测试,来找寻未接收的代码,所以大器晚成旦你使用了 babel 插件的时候,如:babel-preset-env,它暗中同意会将模块打包成commonjs,那样就能让Tree Shaking失效了。

实在在 webpack 2 随后它谐和就扶植模块化管理。所以只要让 babel 不transform modules就能够了。配置如下:

// .babelrc { "presets": [ ["env", { modules: false, ... }] ] }

1
2
3
4
5
6
7
8
9
// .babelrc
{
  "presets": [
    ["env", {
      modules: false,
      ...
    }]
  ]
}

附带说一下都 8102 年了,请不要在应用babel-preset-esxxxx系列了,请用babel-preset-env,相关小说 再见,babel-preset-2015。

六、webpack样式:

内嵌css(不推荐)、独立的css、公共的css样式;

ng-annotate-loader是用来拍卖angular.js的代码。那是一小段代码:
angular.module('myApp', [])
       .controller('testCtrl',  function ($scope) {});

$scope常常而言的减弱会把它当成参数压缩了。解决的章程,生龙活虎种是写成数组

['$scope', function($scope) {}];
// 或者是
testCtrl.$inject = ['$scope'];

其余生机勃勃种是使用ng-annotate。编写翻译之后,会活动补全

angular.module('myApp', [])
       .controller('testCtrl',  ["$scope", function ($scope) {}]);

下一些剧情

  • 手摸手,带您用合理的架势使用 webpack4 (下)

七、模块化学工业机械制特点:

1、能够包容多模块风格,无痛迁移老项目。
2、一切皆模块,js/css/图片/字体都以模块。
3、静态解析(分明信任关系,输入输出的变量),按需打包,动态加载。(webpack最优越的地点);
webpack提供的loaders能够对文件做预管理,进而达成了全套皆模块。

autoprefixer-loader能够补全css代码

开展阅读

  • Webpack 4 和单页应用入门
  • Webpack 中的 sideEffects 到底该怎么用?
  • 您的 Tree-Shaking 并不要紧卵用
  • 对 webpack 文书档案的作弄
  • Tree-Shaking 质量优化执行 – 原理篇
  • 再见,babel-preset-2015

    1 赞 收藏 评论

图片 18

八、webpack对模块做了何等?

(1)非模块化代码;(2)Runtime & 模块;(3)英特尔模块;(4)CommonJs;

图片base64编码

图片这里运用url-loader,会过滤图片。
limit=8192 : 将图片大小小于8K的转为base64编码。
name=images/[name].[ext] : 大于8k的图形则寄放到dist/images底下。

九、代码分块:chunk--程序块;

(1)CommonJs require.ensure(dependencies, callback);
(2)AMD require(dependencies, callback)

webpack sourcemap

调解的时候或许要求领悟这些页面临应了怎么文件。这里将要用到sourcemap。能够使用命令webpack -d去生成,或者在webpack.config.js中配置devtool
实际上调节和测验超多时候根本依旧看样式来自哪个文件。所以这里大致一点,要是是测验情形。css-loader文件前边加上sourcemap。那标准编写翻译的文件小,速度也快一些。作者不时候配置devtool不起效果。也不清楚为什么。
{ test: /.css$/, loader: "style!css?sourceMap!autoprefixer" }

十、分块类型:

(1)入口块 entry chunk;(2)普通块 normal chunk;
(3)伊始块 initial chunk;(4)多入口块;

生成index.html

每一回生成的bundle.js文件因为含有hash,所以都以差别的。无法在index.html里边直接引入。这里要用到一个插件html-webpack-plugin根据模板生成index.html页面(github地址)。
安装:npm install html-webpack-plugin --save-dev
引入:var HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    ...
    plugins: [                                       
        new HtmlWebpackPlugin({        
            filename: path.resolve([输出路径], 'index.html'),
            template: path.resolve([输入路径], "index_template.html")
        })
    ]
}

在模板index_template.html没有必要引进bundle.js。生成index.html会活动引进。

十一、gulp&webpack整合:

▍第三步:编写翻译打包项目工程

1、目的:

前端工程化;越来越好的保管前端代码;

webpack常用命令:
$ webpack        // 最基本的启动webpack方法
$ webpack -w     // 提供watch方法,实时进行打包更新
$ webpack -p     // 对打包后的文件进行压缩
$ webpack -d     // 提供source map,方便调试。

2、怎么管理:

gulp:管理html压缩/预管理/条件编写翻译,图片压缩,Smart图自动合併等任务;
webpack:管理模块化,营造js/css。

情状安排(webpack.config.js)
"scripts": {
  "production": "set NODE_ENV=production && webpack -p",
    "test" : "set NODE_ENV=test && webpack"
}

执行npm run production / npm run test
那是先前的做法。通过设置境况变量NODE_ENV来决断打包的情况。在webpack.config.js中经过process.env.NODE_ENV获取那些值。
发觉在mac上是能够的,但在windows底下。scripts中采纳&&是有时常的。后来改了弹指间。直接把webpack -p那些命令当作生产条件。别的就是调节和测量试验。

3、怎么构成:

(1)webpack-stream方案[不推荐];
(2)webpack原生方案;

获取到指令的第一个参数,为-p则决断为分娩条件。
var isProductEnv = process.argv[2] === '-p';

接下来也许需求差异条件安排部分变量。举个例子说HTTP供给之处。因为那些都归属类型的剧情。就不想在webpack.config.js中布署。直接配置到app文件夹中。在档期的顺序中决断当前意况,require对应的JSON数据。

// webpack.config.js
var DefinePlugin = require('webpack').DefinePlugin;
var definePlugins = new DefinePlugin({
    webpack_prod : isProductEnv
});
module.exports = {
    ...
    plugins: [                                       
        definePlugins,
        ...
    ]
}
// index.js
if (webpack_prod) {
    require('./env/product');
} else {
    require('./env/test');
}

十三、怎么组织代码:

gulp那风度翩翩套、webpack原生方案;

webpack-dev-server本地webserver

启动:webpack-dev-server
地址:http://localhost:port/webpack-dev-server/dist/index.html
文书档案地址 :webpack-dev-server文档
端口号暗中认可是8080,能够在devServer中退换。每便改代码保存后,会活动编写翻译何况刷新页面。还足以成功热替换即不刷新页面能够创新。除此而外还会有几个proxy功能可以用来安排代理。

十八、特别重申--webpack最优良的地点:

预管理;按需加载;

webpack提供的require()方法和require.ensure()方法来促成,即英特尔和commonJS标准;

压缩成项目名称_版本号.zip

使用node.js的插件zip-local
设置并投入项目中:
npm install zip-local --save-dev
品类目录下创立zip.js文件

// 从package.json文件中获取到项目名称和版本号
var packageInfo = require('./package.json');
var zip = packageInfo.name   "_"   packageInfo.version;
// 引入插件
var zipper = require('zip-local');
// 压缩dist文件夹
zipper.sync.zip("dist/").compress().save(zip   ".zip");

奉行命令行 node zip 生成zip压缩文件。

十一、按需加载的时间戳:

rake任务;

▍第四步:开启nginx的gzip功能

webpack打包编写翻译后成叁个文本,文件会比按需加载大。web项目在首先次加载的时候,文件太大的话会相当慢。所以要想艺术把它的体积变小再变小。

十七、常用插件:

1、拆解解析压缩美化chunk:UglifyJsPlugin new webpack.optimize.UglifyJsPlugin([options]);
2、分离css文件;ExtractTextPlugin var ExtractTextPlugin = require("extract-text-webpack-plugin");
3、删除重复依赖;DedupePlugin new webpack.optimize.DedupePlugin(卡塔尔国;
4、跳过编写翻译出错并记录;NoErrorsPlugin new webpack.NoErrorsPlugin(卡塔尔国;
5、提取公共模块;CommonsChunkPlugin new webpack.optimize.CommonsChunkPlugin(options卡塔尔国;

未压缩前,推行命令webpack

![](https://github.com/n98745/MarkdownPhotos/blob/master/webpack/3D5D26AE-AD6E-464E-8AB6-04490118096A.png?raw=true =100x100)

先选拔webpack自带的回落,施行命令webpack -p

![](https://github.com/n98745/MarkdownPhotos/blob/master/webpack/20E389BE-0ABB-405D-8DD4-08B94D599BD1.png?raw=true =100x100)

开启nginx的gzip功能

法定文书档案:Module ngx_http_gzip_module
翻译:Nginx官方文书档案翻译--ngx_http_gzip_module模块

gzip on;
gzip_proxied any;
gzip_disable "msie6";
gzip_comp_level 3;
gzip_min_length 4k;
gzip_types text/css text/xml application/javascript;
开启后:

![](https://github.com/n98745/MarkdownPhotos/blob/master/webpack/5C448E36-480C-4071-8240-33BC35A48896.png?raw=true =100x100)
那标准就把大家正好接近2M的品种代码压缩到150Kb。

▍webpack模块化

webpack帮衬CommonJs和Intel标准。后面一个是同台加载,前者是异步加载。webpack加载的对象是module。它把静态财富都看成是模块。不唯有只是js。还应该有css、html、图片等等都可以由此require去引进,如引进图片:

var img = document.createElement("img");
img.src = require("../image/xxx.jpg");
document.body.appendChild(img);

模块输出:module.exports = ...

webpack resolve

以此是在webpack.config.js中去安顿的五个指标。它的多少个用法:

1. extensions
// 当后缀名为空的时候,会自动识别并不缺
resolve: { 
       extensions: ['', '.js'] 
}  
2. alias
// 通过别名可以减少打包时间,项目中直接require("consts")重定向到指定的文件。
resolve: { 
      alias: { 
          consts: path.resolve(__dirname, "app/util/constant.js")
      } 
} 
全局引进

不常候像jquery想要给它配置全局,使用$去引入。
第豆蔻年华安装重视到品种中
npm install --save-dev jquery
配置plugins,然后就能够在品种中利用。

plugins:[
    new webpack.ProvidePlugin({
        $:"jquery"
    })
]
引进正视

类型中要采纳angular,npm install --save-dev angular把注重下载到文件夹node_modules中。
通过require("angular")可以直接引入

本文由pc28.am发布于前端技术,转载请注明出处:webpack搭建vue最全深入分析,带您用合理的架子使

上一篇:Promise原理解析,让你彻底明白Promise原理 下一篇:没有了
猜你喜欢
热门排行
精彩图文