}
]
},
/* config.module.rule(‘media’) */
{
test: /.(mp4|webm|ogg|mp3|wav|flac|aac)(?.*)?$/,
use: [
/* config.module.rule(‘media’).use(‘url-loader’) */
{
loader: ‘//node_modules/url-loader/dist/cjs.js’,
options: {
limit: 4096,
fallback: {
loader: ‘//node_modules/file-loader/dist/cjs.js’,
options: {
name: ‘media/[name].[hash:8].[ext]’
}
}
}
}
]
},
/* config.module.rule(‘fonts’) */
{
test: /.(woff2?|eot|ttf|otf)(?.*)?$/i,
use: [
/* config.module.rule(‘fonts’).use(‘url-loader’) */
{
loader: ‘//node_modules/url-loader/dist/cjs.js’,
options: {
limit: 4096,
fallback: {
loader: ‘//node_modules/file-loader/dist/cjs.js’,
options: {
name: ‘fonts/[name].[hash:8].[ext]’
}
}
}
}
]
},
/* config.module.rule(‘pug’) */
{
test: /.pug$/,
oneOf: [
/* config.module.rule(‘pug’).oneOf(‘pug-vue’) */
{
resourceQuery: /vue/,
use: [
/* config.module.rule(‘pug’).oneOf(‘pug-vue’).use(‘pug-plain-loader’) */
{
loader: ‘pug-plain-loader’
}
]
},
/* config.module.rule(‘pug’).oneOf(‘pug-template’) */
{
use: [
/* config.module.rule(‘pug’).oneOf(‘pug-template’).use(‘raw’) */
{
loader: ‘raw-loader’
},
/* config.module.rule(‘pug’).oneOf(‘pug-template’).use(‘pug-plain-loader’) */
{
loader: ‘pug-plain-loader’
}
]
}
]
},
/* config.module.rule(‘css’) */
{
test: /.css$/,
oneOf: [
/* config.module.rule(‘css’).oneOf(‘vue-modules’) */
{
resourceQuery: /module/,
use: [
/* config.module.rule(‘css’).oneOf(‘vue-modules’).use(‘extract-css-loader’) */
{
loader: ‘//node_modules/mini-css-extract-plugin/dist/loader.js’,
options: {
hmr: false,
publicPath: ‘…/’
}
},
/* config.module.rule(‘css’).oneOf(‘vue-modules’).use(‘css-loader’) */
{
loader: ‘//node_modules/css-loader/dist/cjs.js’,
options: {
sourceMap: false,
importLoaders: 2,
modules: {
localIdentName: ‘[name][local][hash:base64:5]’
}
}
},
/* config.module.rule(‘css’).oneOf(‘vue-modules’).use(‘postcss-loader’) */
{
loader: ‘//node_modules/postcss-loader/src/index.js’,
options: {
sourceMap: false,
plugins: [
function () { /* omitted long function */
}
]
}
}
]
},
/* config.module.rule(‘css’).oneOf(‘vue’) */
{
resourceQuery: /?vue/,
use: [
/* config.module.rule(‘css’).oneOf(‘vue’).use(‘extract-css-loader’) */
{
loader: ‘//node_modules/mini-css-extract-plugin/dist/loader.js’,
options: {
hmr: false,
publicPath: ‘…/’
}
},
/* config.module.rule(‘css’).oneOf(‘vue’).use(‘css-loader’) */
{
loader: ‘//node_modules/css-loader/dist/cjs.js’,
options: {
sourceMap: false,
importLoaders: 2
}
},
/* config.module.rule(‘css’).oneOf(‘vue’).use(‘postcss-loader’) */
{
loader: ‘//node_modules/postcss-loader/src/index.js’,
options: {
sourceMap: false,
plugins: [
function () { /* omitted long function */
}
]
}
}
]
},
/* config.module.rule(‘css’).oneOf(‘normal-modules’) */
{
test: /.module.\w+$/,
use: [
/* config.module.rule(‘css’).oneOf(‘normal-modules’).use(‘extract-css-loader’) */
{
loader: ‘//node_modules/mini-css-extract-plugin/dist/loader.js’,
options: {
hmr: false,
publicPath: ‘…/’
}
},
/* config.module.rule(‘css’).oneOf(‘normal-modules’).use(‘css-loader’) */
{
loader: ‘//node_modules/css-loader/dist/cjs.js’,
options: {
sourceMap: false,
importLoaders: 2,
modules: {
localIdentName: ‘[name][local][hash:base64:5]’
}
}
},
/* config.module.rule(‘css’).oneOf(‘normal-modules’).use(‘postcss-loader’) */
{
loader: ‘//node_modules/postcss-loader/src/index.js’,
options: {
sourceMap: false,
plugins: [
function () { /* omitted long function */
}
]
}
}
]
},
/* config.module.rule(‘css’).oneOf(‘normal’) */
{
use: [
/* config.module.rule(‘css’).oneOf(‘normal’).use(‘extract-css-loader’) */
{
loader: ‘//node_modules/mini-css-extract-plugin/dist/loader.js’,
options: {
hmr: false,
publicPath: ‘…/’
}
},
/* config.module.rule(‘css’).oneOf(‘normal’).use(‘css-loader’) */
{
loader: ‘//node_modules/css-loader/dist/cjs.js’,
options: {
sourceMap: false,
importLoaders: 2
}
},
/* config.module.rule(‘css’).oneOf(‘normal’).use(‘postcss-loader’) */
{
loader: ‘//node_modules/postcss-loader/src/index.js’,
options: {
sourceMap: false,
plugins: [
function () { /* omitted long function */
}
]
}
}
]
}
]
},
/* config.module.rule(‘postcss’) */
{
test: /.p(ost)?css$/,
oneOf: [
/* config.module.rule(‘postcss’).oneOf(‘vue-modules’) */
{
resourceQuery: /module/,
use: [
/* config.module.rule(‘postcss’).oneOf(‘vue-modules’).use(‘extract-css-loader’) */
{
loader: ‘//node_modules/mini-css-extract-plugin/dist/loader.js’,
options: {
hmr: false,
publicPath: ‘…/’
}
},
/* config.module.rule(‘postcss’).oneOf(‘vue-modules’).use(‘css-loader’) */
{
loader: ‘//node_modules/css-loader/dist/cjs.js’,
options: {
sourceMap: false,
importLoaders: 2,
modules: {
localIdentName: ‘[name][local][hash:base64:5]’
}
}
},
/* config.module.rule(‘postcss’).oneOf(‘vue-modules’).use(‘postcss-loader’) */
{
loader: ‘//node_modules/postcss-loader/src/index.js’,
options: {
sourceMap: false,
plugins: [
function () { /* omitted long function */
}
]
}
}
]
},
/* config.module.rule(‘postcss’).oneOf(‘vue’) */
{
resourceQuery: /?vue/,
use: [
/* config.module.rule(‘postcss’).oneOf(‘vue’).use(‘extract-css-loader’) */
{
loader: ‘//node_modules/mini-css-extract-plugin/dist/loader.js’,
options: {
hmr: false,
publicPath: ‘…/’
}
},
/* config.module.rule(‘postcss’).oneOf(‘vue’).use(‘css-loader’) */
{
loader: ‘//node_modules/css-loader/dist/cjs.js’,
options: {
sourceMap: false,
importLoaders: 2
}
},
/* config.module.rule(‘postcss’).oneOf(‘vue’).use(‘postcss-loader’) */
{
loader: ‘//node_modules/postcss-loader/src/index.js’,
options: {
sourceMap: false,
plugins: [
function () { /* omitted long function */
}
]
}
}
]
},
/* config.module.rule(‘postcss’).oneOf(‘normal-modules’) */
{
test: /.module.\w+$/,
use: [
/* config.module.rule(‘postcss’).oneOf(‘normal-modules’).use(‘extract-css-loader’) */
{
loader: ‘//node_modules/mini-css-extract-plugin/dist/loader.js’,
options: {
hmr: false,
publicPath: ‘…/’
}
},
/* config.module.rule(‘postcss’).oneOf(‘normal-modules’).use(‘css-loader’) */
{
loader: ‘//node_modules/css-loader/dist/cjs.js’,
options: {
sourceMap: false,
importLoaders: 2,
modules: {
localIdentName: ‘[name][local][hash:base64:5]’
}
}
},
/* config.module.rule(‘postcss’).oneOf(‘normal-modules’).use(‘postcss-loader’) */
{
loader: ‘//node_modules/postcss-loader/src/index.js’,
options: {
sourceMap: false,
plugins: [
function () { /* omitted long function */
}
]
}
}
]
},
/* config.module.rule(‘postcss’).oneOf(‘normal’) */
{
use: [
/* config.module.rule(‘postcss’).oneOf(‘normal’).use(‘extract-css-loader’) */
{
loader: ‘//node_modules/mini-css-extract-plugin/dist/loader.js’,
options: {
hmr: false,
publicPath: ‘…/’
}
},
/* config.module.rule(‘postcss’).oneOf(‘normal’).use(‘css-loader’) */
{
loader: ‘//node_modules/css-loader/dist/cjs.js’,
options: {
sourceMap: false,
importLoaders: 2
}
},
/* config.module.rule(‘postcss’).oneOf(‘normal’).use(‘postcss-loader’) */
{
loader: ‘//node_modules/postcss-loader/src/index.js’,
options: {
sourceMap: false,
plugins: [
function () { /* omitted long function */
}
]
}
}
]
}
]
},
/* config.module.rule(‘scss’) */
{
test: /.scss$/,
oneOf: [
/* config.module.rule(‘scss’).oneOf(‘vue-modules’) */
{
resourceQuery: /module/,
use: [
/* config.module.rule(‘scss’).oneOf(‘vue-modules’).use(‘extract-css-loader’) */
{
loader: ‘//node_modules/mini-css-extract-plugin/dist/loader.js’,
options: {
hmr: false,
publicPath: ‘…/’
}
},
/* config.module.rule(‘scss’).oneOf(‘vue-modules’).use(‘css-loader’) */
{
loader: ‘//node_modules/css-loader/dist/cjs.js’,
options: {
sourceMap: false,
importLoaders: 2,
modules: {
localIdentName: ‘[name][local][hash:base64:5]’
}
}
},
/* config.module.rule(‘scss’).oneOf(‘vue-modules’).use(‘postcss-loader’) */
{
loader: ‘//node_modules/postcss-loader/src/index.js’,
options: {
sourceMap: false,
plugins: [
function () { /* omitted long function */
}
]
}
},
/* config.module.rule(‘scss’).oneOf(‘vue-modules’).use(‘sass-loader’) */
{
loader: ‘sass-loader’,
options: {
sourceMap: false
}
}
]
},
/* config.module.rule(‘scss’).oneOf(‘vue’) */
{
resourceQuery: /?vue/,
use: [
/* config.module.rule(‘scss’).oneOf(‘vue’).use(‘extract-css-loader’) */
{
loader: ‘//node_modules/mini-css-extract-plugin/dist/loader.js’,
options: {
hmr: false,
publicPath: ‘…/’
}
},
/* config.module.rule(‘scss’).oneOf(‘vue’).use(‘css-loader’) */
{
loader: ‘//node_modules/css-loader/dist/cjs.js’,
options: {
sourceMap: false,
importLoaders: 2
}
},
/* config.module.rule(‘scss’).oneOf(‘vue’).use(‘postcss-loader’) */
{
loader: ‘//node_modules/postcss-loader/src/index.js’,
options: {
sourceMap: false,
plugins: [
function () { /* omitted long function */
}
]
}
},
/* config.module.rule(‘scss’).oneOf(‘vue’).use(‘sass-loader’) */
{
loader: ‘sass-loader’,
options: {
sourceMap: false
}
}
]
},
/* config.module.rule(‘scss’).oneOf(‘normal-modules’) */
{
test: /.module.\w+$/,
use: [
/* config.module.rule(‘scss’).oneOf(‘normal-modules’).use(‘extract-css-loader’) */
{
loader: ‘//node_modules/mini-css-extract-plugin/dist/loader.js’,
options: {
hmr: false,
publicPath: ‘…/’
}
},
/* config.module.rule(‘scss’).oneOf(‘normal-modules’).use(‘css-loader’) */
{
loader: ‘//node_modules/css-loader/dist/cjs.js’,
options: {
sourceMap: false,
importLoaders: 2,
modules: {
localIdentName: ‘[name][local][hash:base64:5]’
}
}
},
/* config.module.rule(‘scss’).oneOf(‘normal-modules’).use(‘postcss-loader’) */
{
loader: ‘//node_modules/postcss-loader/src/index.js’,
options: {
sourceMap: false,
plugins: [
function () { /* omitted long function */
}
]
}
},
/* config.module.rule(‘scss’).oneOf(‘normal-modules’).use(‘sass-loader’) */
{
loader: ‘sass-loader’,
options: {
sourceMap: false
}
}
]
},
/* config.module.rule(‘scss’).oneOf(‘normal’) */
{
use: [
/* config.module.rule(‘scss’).oneOf(‘normal’).use(‘extract-css-loader’) */
{
loader: ‘//node_modules/mini-css-extract-plugin/dist/loader.js’,
options: {
hmr: false,
publicPath: ‘…/’
}
},
/* config.module.rule(‘scss’).oneOf(‘normal’).use(‘css-loader’) */
{
loader: ‘//node_modules/css-loader/dist/cjs.js’,
options: {
sourceMap: false,
importLoaders: 2
}
},
/* config.module.rule(‘scss’).oneOf(‘normal’).use(‘postcss-loader’) */
{
loader: ‘//node_modules/postcss-loader/src/index.js’,
options: {
sourceMap: false,
plugins: [
function () { /* omitted long function */
}
]
}
},
/* config.module.rule(‘scss’).oneOf(‘normal’).use(‘sass-loader’) */
{
loader: ‘sass-loader’,
options: {
sourceMap: false
}
}
]
}
]
},
/* config.module.rule(‘sass’) */
{
test: /.sass$/,
oneOf: [
/* config.module.rule(‘sass’).oneOf(‘vue-modules’) */
{
resourceQuery: /module/,
use: [
/* config.module.rule(‘sass’).oneOf(‘vue-modules’).use(‘extract-css-loader’) */
{
loader: ‘//node_modules/mini-css-extract-plugin/dist/loader.js’,
options: {
hmr: false,
publicPath: ‘…/’
}
},
/* config.module.rule(‘sass’).oneOf(‘vue-modules’).use(‘css-loader’) */
{
loader: ‘//node_modules/css-loader/dist/cjs.js’,
options: {
sourceMap: false,
importLoaders: 2,
modules: {
localIdentName: ‘[name][local][hash:base64:5]’
}
}
},
/* config.module.rule(‘sass’).oneOf(‘vue-modules’).use(‘postcss-loader’) */
{
loader: ‘//node_modules/postcss-loader/src/index.js’,
options: {
sourceMap: false,
plugins: [
function () { /* omitted long function */
}
]
}
},
/* config.module.rule(‘sass’).oneOf(‘vue-modules’).use(‘sass-loader’) */
{
loader: ‘sass-loader’,
options: {
sourceMap: false,
sassOptions: {
indentedSyntax: true
}
}
}
]
},
/* config.module.rule(‘sass’).oneOf(‘vue’) */
{
resourceQuery: /?vue/,
use: [
/* config.module.rule(‘sass’).oneOf(‘vue’).use(‘extract-css-loader’) */
{
loader: ‘//node_modules/mini-css-extract-plugin/dist/loader.js’,
options: {
hmr: false,
publicPath: ‘…/’
}
},
/* config.module.rule(‘sass’).oneOf(‘vue’).use(‘css-loader’) */
{
loader: ‘//node_modules/css-loader/dist/cjs.js’,
options: {
sourceMap: false,
importLoaders: 2
}
},
/* config.module.rule(‘sass’).oneOf(‘vue’).use(‘postcss-loader’) */
{
loader: ‘//node_modules/postcss-loader/src/index.js’,
options: {
sourceMap: false,
plugins: [
function () { /* omitted long function */
}
]
}
},
/* config.module.rule(‘sass’).oneOf(‘vue’).use(‘sass-loader’) */
{
loader: ‘sass-loader’,
options: {
sourceMap: false,
sassOptions: {
indentedSyntax: true
}
}
}
]
},
/* config.module.rule(‘sass’).oneOf(‘normal-modules’) */
{
test: /.module.\w+$/,
use: [
/* config.module.rule(‘sass’).oneOf(‘normal-modules’).use(‘extract-css-loader’) */
{
loader: ‘//node_modules/mini-css-extract-plugin/dist/loader.js’,
options: {
hmr: false,
publicPath: ‘…/’
}
},
/* config.module.rule(‘sass’).oneOf(‘normal-modules’).use(‘css-loader’) */
{
loader: ‘//node_modules/css-loader/dist/cjs.js’,
options: {
sourceMap: false,
importLoaders: 2,
modules: {
localIdentName: ‘[name][local][hash:base64:5]’
}
}
},
/* config.module.rule(‘sass’).oneOf(‘normal-modules’).use(‘postcss-loader’) */
{
loader: ‘//node_modules/postcss-loader/src/index.js’,
options: {
sourceMap: false,
plugins: [
function () { /* omitted long function */
}
]
}
},
/* config.module.rule(‘sass’).oneOf(‘normal-modules’).use(‘sass-loader’) */
{
loader: ‘sass-loader’,
options: {
sourceMap: false,
sassOptions: {
indentedSyntax: true
}
}
}
]
},
/* config.module.rule(‘sass’).oneOf(‘normal’) */
{
use: [
/* config.module.rule(‘sass’).oneOf(‘normal’).use(‘extract-css-loader’) */
{
loader: ‘//node_modules/mini-css-extract-plugin/dist/loader.js’,
options: {
hmr: false,
publicPath: ‘…/’
}
},
/* config.module.rule(‘sass’).oneOf(‘normal’).use(‘css-loader’) */
{
loader: ‘//node_modules/css-loader/dist/cjs.js’,
options: {
sourceMap: false,
importLoaders: 2
}
},
/* config.module.rule(‘sass’).oneOf(‘normal’).use(‘postcss-loader’) */
{
loader: ‘//node_modules/postcss-loader/src/index.js’,
options: {
sourceMap: false,
plugins: [
function () { /* omitted long function */
}
]
}
},
/* config.module.rule(‘sass’).oneOf(‘normal’).use(‘sass-loader’) */
{
loader: ‘sass-loader’,
options: {
sourceMap: false,
sassOptions: {
indentedSyntax: true
}
}
}
]
}
]
},
/* config.module.rule(‘less’) */
{
test: /.less$/,
oneOf: [
/* config.module.rule(‘less’).oneOf(‘vue-modules’) */
{
resourceQuery: /module/,
use: [
/* config.module.rule(‘less’).oneOf(‘vue-modules’).use(‘extract-css-loader’) */
{
loader: ‘//node_modules/mini-css-extract-plugin/dist/loader.js’,
options: {
hmr: false,
publicPath: ‘…/’
}
},
/* config.module.rule(‘less’).oneOf(‘vue-modules’).use(‘css-loader’) */
{
loader: ‘//node_modules/css-loader/dist/cjs.js’,
options: {
sourceMap: false,
importLoaders: 2,
modules: {
localIdentName: ‘[name][local][hash:base64:5]’
}
}
},
/* config.module.rule(‘less’).oneOf(‘vue-modules’).use(‘postcss-loader’) */
{
loader: ‘//node_modules/postcss-loader/src/index.js’,
options: {
sourceMap: false,
plugins: [
function () { /* omitted long function */
}
]
}
},
/* config.module.rule(‘less’).oneOf(‘vue-modules’).use(‘less-loader’) */
{
loader: ‘less-loader’,
options: {
sourceMap: false
}
}
]
},
/* config.module.rule(‘less’).oneOf(‘vue’) */
{
resourceQuery: /?vue/,
use: [
/* config.module.rule(‘less’).oneOf(‘vue’).use(‘extract-css-loader’) */
{
loader: ‘//node_modules/mini-css-extract-plugin/dist/loader.js’,
options: {
hmr: false,
publicPath: ‘…/’
}
},
/* config.module.rule(‘less’).oneOf(‘vue’).use(‘css-loader’) */
{
loader: ‘//node_modules/css-loader/dist/cjs.js’,
options: {
sourceMap: false,
importLoaders: 2
}
},
/* config.module.rule(‘less’).oneOf(‘vue’).use(‘postcss-loader’) */
{
loader: ‘//node_modules/postcss-loader/src/index.js’,
options: {
sourceMap: false,
plugins: [
function () { /* omitted long function */
}
]
}
},
/* config.module.rule(‘less’).oneOf(‘vue’).use(‘less-loader’) */
{
loader: ‘less-loader’,
options: {
sourceMap: false
}
}
]
},
/* config.module.rule(‘less’).oneOf(‘normal-modules’) */
{
test: /.module.\w+$/,
use: [
/* config.module.rule(‘less’).oneOf(‘normal-modules’).use(‘extract-css-loader’) */
{
loader: ‘//node_modules/mini-css-extract-plugin/dist/loader.js’,
options: {
hmr: false,
publicPath: ‘…/’
}
},
/* config.module.rule(‘less’).oneOf(‘normal-modules’).use(‘css-loader’) */
{
loader: ‘//node_modules/css-loader/dist/cjs.js’,
options: {
sourceMap: false,
importLoaders: 2,
modules: {
localIdentName: ‘[name][local][hash:base64:5]’
}
}
},
/* config.module.rule(‘less’).oneOf(‘normal-modules’).use(‘postcss-loader’) */
{
loader: ‘//node_modules/postcss-loader/src/index.js’,
options: {
sourceMap: false,
plugins: [
function () { /* omitted long function */
}
]
}
},
/* config.module.rule(‘less’).oneOf(‘normal-modules’).use(‘less-loader’) */
{
loader: ‘less-loader’,
options: {
sourceMap: false
}
}
]
},
/* config.module.rule(‘less’).oneOf(‘normal’) */
{
use: [
/* config.module.rule(‘less’).oneOf(‘normal’).use(‘extract-css-loader’) */
{
loader: ‘//node_modules/mini-css-extract-plugin/dist/loader.js’,
options: {
hmr: false,
publicPath: ‘…/’
}
},
/* config.module.rule(‘less’).oneOf(‘normal’).use(‘css-loader’) */
{
loader: ‘//node_modules/css-loader/dist/cjs.js’,
options: {
sourceMap: false,
importLoaders: 2
}
},
/* config.module.rule(‘less’).oneOf(‘normal’).use(‘postcss-loader’) */
{
loader: ‘//node_modules/postcss-loader/src/index.js’,
options: {
sourceMap: false,
plugins: [
function () { /* omitted long function */
}
]
}
},
/* config.module.rule(‘less’).oneOf(‘normal’).use(‘less-loader’) */
{
loader: ‘less-loader’,
options: {
sourceMap: false
}
}
]
}
]
},
/* config.module.rule(‘stylus’) */
{
test: /.styl(us)?$/,
oneOf: [
/* config.module.rule(‘stylus’).oneOf(‘vue-modules’) */
{
resourceQuery: /module/,
use: [
/* config.module.rule(‘stylus’).oneOf(‘vue-modules’).use(‘extract-css-loader’) */
{
loader: ‘//node_modules/mini-css-extract-plugin/dist/loader.js’,
options: {
hmr: false,
publicPath: ‘…/’
}
},
/* config.module.rule(‘stylus’).oneOf(‘vue-modules’).use(‘css-loader’) */
{
loader: ‘//node_modules/css-loader/dist/cjs.js’,
options: {
sourceMap: false,
importLoaders: 2,
modules: {
localIdentName: ‘[name][local][hash:base64:5]’
}
}
},
/* config.module.rule(‘stylus’).oneOf(‘vue-modules’).use(‘postcss-loader’) */
{
loader: ‘//node_modules/postcss-loader/src/index.js’,
options: {
sourceMap: false,
plugins: [
function () { /* omitted long function */
}
]
}
},
/* config.module.rule(‘stylus’).oneOf(‘vue-modules’).use(‘stylus-loader’) */
{
loader: ‘stylus-loader’,
options: {
sourceMap: false,
preferPathResolver: ‘webpack’
}
}
]
},
/* config.module.rule(‘stylus’).oneOf(‘vue’) */
{
resourceQuery: /?vue/,
use: [
/* config.module.rule(‘stylus’).oneOf(‘vue’).use(‘extract-css-loader’) */
{
loader: ‘//node_modules/mini-css-extract-plugin/dist/loader.js’,
options: {
hmr: false,
publicPath: ‘…/’
}
},
/* config.module.rule(‘stylus’).oneOf(‘vue’).use(‘css-loader’) */
{
loader: ‘//node_modules/css-loader/dist/cjs.js’,
options: {
sourceMap: false,
importLoaders: 2
}
},
/* config.module.rule(‘stylus’).oneOf(‘vue’).use(‘postcss-loader’) */
{
loader: ‘//node_modules/postcss-loader/src/index.js’,
options: {
sourceMap: false,
plugins: [
function () { /* omitted long function */
}
]
}
},
/* config.module.rule(‘stylus’).oneOf(‘vue’).use(‘stylus-loader’) */
{
loader: ‘stylus-loader’,
options: {
sourceMap: false,
preferPathResolver: ‘webpack’
}
}
]
},
/* config.module.rule(‘stylus’).oneOf(‘normal-modules’) */
{
test: /.module.\w+$/,
use: [
/* config.module.rule(‘stylus’).oneOf(‘normal-modules’).use(‘extract-css-loader’) */
{
loader: ‘//node_modules/mini-css-extract-plugin/dist/loader.js’,
options: {
hmr: false,
publicPath: ‘…/’
}
},
/* config.module.rule(‘stylus’).oneOf(‘normal-modules’).use(‘css-loader’) */
{
loader: ‘//node_modules/css-loader/dist/cjs.js’,
options: {
sourceMap: false,
importLoaders: 2,
modules: {
localIdentName: ‘[name][local][hash:base64:5]’
}
}
},
/* config.module.rule(‘stylus’).oneOf(‘normal-modules’).use(‘postcss-loader’) */
{
loader: ‘//node_modules/postcss-loader/src/index.js’,
options: {
sourceMap: false,
plugins: [
function () { /* omitted long function */
}
]
}
},
/* config.module.rule(‘stylus’).oneOf(‘normal-modules’).use(‘stylus-loader’) */
{
loader: ‘stylus-loader’,
options: {
sourceMap: false,
preferPathResolver: ‘webpack’
}
}
]
},
/* config.module.rule(‘stylus’).oneOf(‘normal’) */
{
use: [
/* config.module.rule(‘stylus’).oneOf(‘normal’).use(‘extract-css-loader’) */
{
loader: ‘//node_modules/mini-css-extract-plugin/dist/loader.js’,
options: {
hmr: false,
publicPath: ‘…/’
}
},
/* config.module.rule(‘stylus’).oneOf(‘normal’).use(‘css-loader’) */
{
loader: ‘//node_modules/css-loader/dist/cjs.js’,
options: {
sourceMap: false,
importLoaders: 2
}
},
/* config.module.rule(‘stylus’).oneOf(‘normal’).use(‘postcss-loader’) */
{
loader: ‘//node_modules/postcss-loader/src/index.js’,
options: {
sourceMap: false,
plugins: [
function () { /* omitted long function */
}
]
}
},
/* config.module.rule(‘stylus’).oneOf(‘normal’).use(‘stylus-loader’) */
{
loader: ‘stylus-loader’,
options: {
sourceMap: false,
preferPathResolver: ‘webpack’
}
}
]
}
]
},
/* config.module.rule(‘js’) */
{
test: /.m?jsx?$/,
exclude: [
function () { /* omitted long function */
}
],
use: [
/* config.module.rule(‘js’).use(‘cache-loader’) */
{
loader: ‘//node_modules/cache-loader/dist/cjs.js’,
options: {
cacheDirectory: ‘//node_modules/.cache/babel-loader’,
cacheIdentifier: ‘bf6c8644’
}
},
/* config.module.rule(‘js’).use(‘thread-loader’) */
{
// 多线程打包
loader: ‘//node_modules/thread-loader/dist/cjs.js’
},
/* config.module.rule(‘js’).use(‘babel-loader’) */
{
loader: ‘//node_modules/babel-loader/lib/index.js’
}
]
},
/* config.module.rule(‘eslint’) */
{
enforce: ‘pre’,
test: /.(vue|(j|t)sx?)$/,
exclude: [
/node_modules/,
‘//node_modules/@vue/cli-service/lib’
],
use: [
/* config.module.rule(‘eslint’).use(‘eslint-loader’) */
{
loader: ‘//node_modules/eslint-loader/index.js’,
options: {
extensions: [
‘.js’,
‘.jsx’,
‘.vue’
],
cache: true,
cacheIdentifier: ‘6340a568’,
emitWarning: false,
emitError: false,
eslintPath: ‘//node_modules/eslint’,
formatter: undefined
}
}
]
}
]
},
optimization: {
splitChunks: {
cacheGroups: {
vendors: {
name: ‘chunk-vendors’,
test: /[\/]node_modules[\/]/,
priority: -10,
chunks: ‘initial’
},
common: {
name: ‘chunk-common’,
minChunks: 2,
priority: -20,
chunks: ‘initial’,
reuseExistingChunk: true
}
}
},
minimizer: [
/* config.optimization.minimizer(‘terser’) */
new TerserPlugin(
{
terserOptions: {
compress: {
arrows: false,
collapse_vars: false,
comparisons: false,
computed_props: false,
hoist_funs: false,
hoist_props: false,
hoist_vars: false,
inline: false,
loops: false,
negate_iife: false,
properties: false,
reduce_funcs: false,
reduce_vars: false,
switches: false,
toplevel: false,
typeofs: false,
booleans: true,
if_return: true,
sequences: true,
unused: true,
conditionals: true,
dead_code: true,
evaluate: true
},
mangle: {
safari10: true
}
},
sourceMap: true,
cache: true,
parallel: true,
extractComments: false
}
)
]
},
plugins: [
/* config.plugin(‘vue-loader’) */
new VueLoaderPlugin(),
/* config.plugin(‘define’) */
new DefinePlugin(
{
‘process.env’: {
NODE_ENV: ‘“production”’,
BASE_URL: ‘“/”’
}
}
),
/* config.plugin(‘case-sensitive-paths’) */
new CaseSensitivePathsPlugin(),
/* config.plugin(‘friendly-errors’) */
new FriendlyErrorsWebpackPlugin(
{
additionalTransformers: [
function () { /* omitted long function */
}
],
additionalFormatters: [
function () { /* omitted long function */
}
]
}
),
/* config.plugin(‘extract-css’) */
new MiniCssExtractPlugin(
{
filename: ‘css/[name].[contenthash:8].css’,
chunkFilename: ‘css/[name].[contenthash:8].css’
}
),
/* config.plugin(‘optimize-css’) */
new OptimizeCssnanoPlugin(
{
sourceMap: false,
cssnanoOptions: {
preset: [
‘default’,
{
mergeLonghand: false,
cssDeclarationSorter: false
}
]
}
}
),
/* config.plugin(‘hash-module-ids’) */
new HashedModuleIdsPlugin(
{
hashDigest: ‘hex’
}
),
/* config.plugin(‘named-chunks’) */
new NamedChunksPlugin(
function () { /* omitted long function */
}
),
/* config.plugin(‘html’) */
new HtmlWebpackPlugin(
{
title: ‘02.vue_cli’,
templateParameters: function () { /* omitted long function */
},
minify: {
removeComments: true,
collapseWhitespace: true,
collapseBooleanAttributes: true,
removeScriptTypeAttributes: true
},
template: ‘//public/index.html’
}
),
/* config.plugin(‘preload’) */
new PreloadPlugin(
{
rel: ‘preload’,
include: ‘initial’,
fileBlacklist: [
/.map$/,
/hot-update.js$/
]
}
),
/* config.plugin(‘prefetch’) */
new PreloadPlugin(
{
rel: ‘prefetch’,
include: ‘asyncChunks’
}
),
/* config.plugin(‘copy’) */
new CopyPlugin(
[
{
from: ‘//public’,
to: ‘//dist’,
toType: ‘dir’,
ignore: [
‘.DS_Store’,
{
glob: ‘index.html’,
matchBase: false
}
]
}
]
)
],
entry: {
app: [
‘./src/main.js’
]
}
}
比较
生产环境css相关loader有些变化,js进行多线程打包,加了一些插件
loader本质上是函数,webpack在调用的时候会将文件传递到函数中,函数处理完成后将结果返回
即:loader是对文件做处理的函数
如果用use指定使用多个loader,那么loader的执行顺序是从下向上(从右向左/从后向前)。
但是loader中可以指定pitch函数,pitch会从前向后执行
module.exports.pitch = function () {
xxx
}
即:在loader中,module.exports函数,会从后向前依次执行,但是module.exports.pitch函数,会从前向后执行
// loader本质上是一个函数
// 同步loader
// module.exports = function (content, map, meta) {
// console.log(111);
// return content;
// }
module.exports = function (content, map, meta) {
console.log(111);
this.callback(null, content, map, meta);
}
module.exports.pitch = function () {
console.log(‘pitch 111’);
}
loader可以使用异步loader,使用this.async()
,并使用callback接收。后续可以做一些异步操作,做完后执行callback才会执行后续操作。
// loader本质上是一个函数
// 异步loader
module.exports = function (content, map, meta) {
console.log(222);
const callback = this.async();
setTimeout(() => {
callback(null, content);
}, 1000)
}
module.exports.pitch = function () {
console.log(‘pitch 222’);
}
在使用loader的时候,会使用options传递一些参数
{
loader: ‘loader3’,
options: {
name: ‘jack’,
age: 18
}
}
可以使用loader-utils
库进行接收参数。
使用方法
// loader本质上是一个函数
const { getOptions } = require(‘loader-utils’);
module.exports = function (content, map, meta) {
// 获取options
const options = getOptions(this);
console.log(333, options);
return content;
}
module.exports.pitch = function () {
console.log(‘pitch 333’);
}
可以使用schema-utils
库进行参数校验。
使用方法:
- 定义
schema.json
确定格式,确定格式描述是否允许追加等信息
{
“type”: “object”,
“properties”: {
“name”: {
“type”: “string”,
“description”: “名称~”
}
},
“additionalProperties”: false
}
其中additionalProperties表示是否可以追加其他属性
- 在loader中进行校验
// loader本质上是一个函数
const {getOptions} = require(‘loader-utils’);
const {validate} = require(‘schema-utils’);
const schema = require(‘./schema’);
module.exports = function (content, map, meta) {
// 获取options
const options = getOptions(this);
console.log(333, options);
// 校验options是否合法
validate(schema, options, {
name: ‘loader3’
})
return content;
}
module.exports.pitch = function () {
console.log(‘pitch 333’);
}
validate接收三个参数,第一个是校验规则,第二个是参数,第三个指定当前loader名称。
自定义babelLaoder
- 定义校验规则
babelSchema.json
{
“type”: “object”,
“properties”: {
“presets”: {
“type”: “array”
}
},
“additionalProperties”: true
}
- 定义babelLoader
const { getOptions } = require(‘loader-utils’);
const { validate } = require(‘schema-utils’);
const babel = require(‘@babel/core’);
const util = require(‘util’);
const babelSchema = require(‘./babelSchema.json’);
// babel.transform用来编译代码的方法
// 是一个普通异步方法
// util.promisify将普通异步方法转化成基于promise的异步方法
const transform = util.promisify(babel.transform);
module.exports = function (content, map, meta) {
// 获取loader的options配置
const options = getOptions(this) || {};
// 校验babel的options的配置
validate(babelSchema, options, {
name: ‘Babel Loader’
});
// 创建异步
const callback = this.async();
// 使用babel编译代码
transform(content, options)
.then(({code, map}) => callback(null, code, map, meta))
.catch((e) => callback(e))
}
Tapable
const {SyncHook, SyncBailHook, AsyncParallelHook, AsyncSeriesHook} = require(‘tapable’);
class Lesson {
constructor() {
// 初始化hooks容器
this.hooks = {
// 同步hooks,任务回依次执行
// go: new SyncHook([‘address’])
// SyncBailHook:一旦有返回值就会退出~
go: new SyncBailHook([‘address’]),
// 异步hooks
// AsyncParallelHook:异步并行
// leave: new AsyncParallelHook([‘name’, ‘age’]),
// AsyncSeriesHook: 异步串行
leave: new AsyncSeriesHook([‘name’, ‘age’])
}
}
tap() {
// 往hooks容器中注册事件/添加回调函数
this.hooks.go.tap(‘class0318’, (address) => {
console.log(‘class0318’, address);
return 111;
})
this.hooks.go.tap(‘class0410’, (address) => {
console.log(‘class0410’, address);
})
this.hooks.leave.tapAsync(‘class0510’, (name, age, cb) => {
setTimeout(() => {
console.log(‘class0510’, name, age);
cb();
}, 2000)
})
this.hooks.leave.tapPromise(‘class0610’, (name, age) => {
return new Promise((resolve) => {
setTimeout(() => {
console.log(‘class0610’, name, age);
resolve();
}, 1000)
})
})
}
start() {
// 触发hooks
this.hooks.go.call(‘c318’);
this.hooks.leave.callAsync(‘jack’, 18, function () {
// 代表所有leave容器中的函数触发完了,才触发
console.log(‘end~~~’);
});
}
}
const l = new Lesson();
l.tap();
l.start();
每一个plugin调用的时候都是通过new进行调用的,所以每一个plugin都是一个构造函数或者类。
每一个插件类中必须有一个apply函数,因为插件是通过这个函数进行调用的,接受compiler
参数
插件就是在webpack不同生命周期内执行不同操作
class Plugin1 {
apply(complier) {
complier.hooks.emit.tap(‘Plugin1’, (compilation) => {
console.log(‘emit.tap 111’);
})
complier.hooks.emit.tapAsync(‘Plugin1’, (compilation, cb) => {
setTimeout(() => {
console.log(‘emit.tapAsync 111’);
cb();
}, 1000)
})
complier.hooks.emit.tapPromise(‘Plugin1’, (compilation) => {
return new Promise((resolve) => {
setTimeout(() => {
console.log(‘emit.tapPromise 111’);
resolve();
}, 1000)
})
})
complier.hooks.afterEmit.tap(‘Plugin1’, (compilation) => {
console.log(‘afterEmit.tap 111’);
})
complier.hooks.done.tap(‘Plugin1’, (stats) => {
console.log(‘done.tap 111’);
})
}
}
module.exports = Plugin1;
node环境中调试
package.json中添加
“scripts”: {
“start”: “node --inspect-brk ./node_modules/webpack/bin/webpack.js”
}
表示以调试的方式启动,并在第一行打断点。调试webpack.js文件。
-
在需要 调试的地方打debugger断点
-
通过node运行文件
-
网页中启动
const fs = require(‘fs’);
const util = requ33333333333333333333333333333333333333333333333333333ire(‘util’);
const path = require(‘path’);
const webpack = require(‘webpack’);
const { RawSource } = webpack.sources;
// 将fs。readFile方法变成基于promise风格的异步方法
const readFile = util.promisify(fs.readFile);
class Plugin2 {
apply(compiler) {
// 初始化compilation钩子
compiler.hooks.thisCompilation.tap(‘Plugin2’, (compilation) => {
// debugger
// console.log(compilation);
// 添加资源
compilation.hooks.additionalAssets.tapAsync(‘Plugin2’, async (cb) => {
// debugger
// console.log(compilation);
const content = ‘hello plugin2’;
// 往要输出资源中,添加一个a.txt
compilation.assets[‘a.txt’] = {
// 文件大小
size() {
return content.length;
},
// 文件内容
source() {
return content;
}
}
const data = await readFile(path.resolve(__dirname, ‘b.txt’));
// compilation.assets[‘b.txt’] = new RawSource(data);
compilation.emitAsset(‘b.txt’, new RawSource(data));
cb();
})
})
}
}
module.exports = Plugin2;
自定义plugin
schema.json
{
“type”: “object”,
“properties”: {
“from”: {
“type”: “string”
},
“to”: {
“type”: “string”
},
“ignore”: {
“type”: “array”
}
},
“additionalProperties”: false
}
CopyWebpackPlugin.js
const path = require(‘path’);
const fs = require(‘fs’);
const {promisify} = require(‘util’)
const {validate} = require(‘schema-utils’);
const globby = require(‘globby’);
const webpack = require(‘webpack’);
const schema = require(‘./schema.json’);
const {Compilation} = require(‘webpack’);
const readFile = promisify(fs.readFile);
const {RawSource} = webpack.sources
class CopyWebpackPlugin {
constructor(options = {}) {
// 验证options是否符合规范
validate(schema, options, {
name: ‘CopyWebpackPlugin’
})
this.options = options;
}
apply(compiler) {
// 初始化compilation
compiler.hooks.thisCompilation.tap(‘CopyWebpackPlugin’, (compilation) => {
// 添加资源的hooks
compilation.hooks.additionalAssets.tapAsync(‘CopyWebpackPlugin’, async (cb) => {
// 将from中的资源复制到to中,输出出去
const {from, ignore} = this.options;
const to = this.options.to ? this.options.to : ‘.’;
// context就是webpack配置
// 运行指令的目录
const context = compiler.options.context; // process.cwd()
// 将输入路径变成绝对路径
const absoluteFrom = path.isAbsolute(from) ? from : path.resolve(context, from);
// 1. 过滤掉ignore的文件
// globby(要处理的文件夹,options)
const paths = await globby(absoluteFrom, {ignore});
console.log(paths); // 所有要加载的文件路径数组
// 2. 读取paths中所有资源
const files = await Promise.all(
paths.map(async (absolutePath) => {
// 读取文件
const data = await readFile(absolutePath);
// basename得到最后的文件名称
const relativePath = path.basename(absolutePath);
// 和to属性结合
// 没有to --> reset.css
// 有to --> css/reset.css
const filename = path.join(to, relativePath);
return {
// 文件数据
data,
// 文件名称
filename
}
})
)
// 3. 生成webpack格式的资源
const assets = files.map((file) => {
const source = new RawSource(file.data);
return {
source,
filename: file.filename
}
})
// 4. 添加compilation中,输出出去
assets.forEach((asset) => {
compilation.emitAsset(asset.filename, asset.source);
})
cb();
})
})
}
}
module.exports = CopyWebpackPlugin;
webpack.config.js中使用
const CopyWebpackPlugin = require(‘./plugins/CopyWebpackPlugin’)
module.exports = {
plugins: [
new CopyWebpackPlugin({
from: ‘public’,
to: ‘css’,
ignore: [‘**/index.html’]
})
]
}
-
初始化Complier:new Webpack(config)得到Complier对象
-
开始编译:调用Compiler对象run方法开始执行编译
-
确定入口:根据配置中的entry找出所有的入口文件
-
编译模块:从入口文件出发,调用所有配置的loader对模块进行编译,再找出该模块依赖的模块,递归直到所有的模块都被加载进来
-
完成模块编译:经过第4步使用Loader编译完所有模块后,得到每个模块被编译后的最终内容以及它们之间的依赖关系
-
输出资源:根据入口和模块之间的依赖关系,组装成一个个包含多个模块的Chunk,再把每个Chunk转换成一个单独的文件加入到输出列表。(注意:这步是可以修改输出内容的最后机会)
-
输出完成:在确定好输出内容后,根据配置正确输出的路径和文件名,把文件内容写入到文件系统
文件 目录
config/webpack.config.js
const path = require(‘path’);
module.exports = {
entry: ‘./src/index.js’,
output: {
path: path.resolve(__dirname, ‘…/dist’),
filename: ‘main.js’
}
}
dist/index.html
dist/main.js
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V:vip1024c 备注前端获取(资料价值较高,非无偿)
总结一下
面试前要精心做好准备,简历上写的知识点和原理都需要准备好,项目上多想想难点和亮点,这是面试时能和别人不一样的地方。
还有就是表现出自己的谦虚好学,以及对于未来持续进阶的规划,企业招人更偏爱稳定的人。
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
万事开头难,但是程序员这一条路坚持几年后发展空间还是非常大的,一切重在坚持。
为了帮助大家更好更高效的准备面试,特别整理了《前端工程师面试手册》电子稿文件。
前端面试题汇总
JavaScript
性能
linux
前端资料汇总
前端工程师岗位缺口一直很大,符合岗位要求的人越来越少,所以学习前端的小伙伴要注意了,一定要把技能学到扎实,做有含金量的项目,这样在找工作的时候无论遇到什么情况,问题都不会大。
.join(to, relativePath);
return {
// 文件数据
data,
// 文件名称
filename
}
})
)
// 3. 生成webpack格式的资源
const assets = files.map((file) => {
const source = new RawSource(file.data);
return {
source,
filename: file.filename
}
})
// 4. 添加compilation中,输出出去
assets.forEach((asset) => {
compilation.emitAsset(asset.filename, asset.source);
})
cb();
})
})
}
}
module.exports = CopyWebpackPlugin;
webpack.config.js中使用
const CopyWebpackPlugin = require(‘./plugins/CopyWebpackPlugin’)
module.exports = {
plugins: [
new CopyWebpackPlugin({
from: ‘public’,
to: ‘css’,
ignore: [‘**/index.html’]
})
]
}
-
初始化Complier:new Webpack(config)得到Complier对象
-
开始编译:调用Compiler对象run方法开始执行编译
-
确定入口:根据配置中的entry找出所有的入口文件
-
编译模块:从入口文件出发,调用所有配置的loader对模块进行编译,再找出该模块依赖的模块,递归直到所有的模块都被加载进来
-
完成模块编译:经过第4步使用Loader编译完所有模块后,得到每个模块被编译后的最终内容以及它们之间的依赖关系
-
输出资源:根据入口和模块之间的依赖关系,组装成一个个包含多个模块的Chunk,再把每个Chunk转换成一个单独的文件加入到输出列表。(注意:这步是可以修改输出内容的最后机会)
-
输出完成:在确定好输出内容后,根据配置正确输出的路径和文件名,把文件内容写入到文件系统
文件 目录
config/webpack.config.js
const path = require(‘path’);
module.exports = {
entry: ‘./src/index.js’,
output: {
path: path.resolve(__dirname, ‘…/dist’),
filename: ‘main.js’
}
}
dist/index.html
dist/main.js
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-A2hZg9EO-1711589644111)]
[外链图片转存中…(img-stShDgAQ-1711589644112)]
[外链图片转存中…(img-w3xFdyUh-1711589644112)]
[外链图片转存中…(img-ZB0lWHgv-1711589644112)]
[外链图片转存中…(img-aTQW7reh-1711589644113)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!
[外链图片转存中…(img-RRrtBpgM-1711589644113)]
[外链图片转存中…(img-1IwJjM0x-1711589644113)]
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V:vip1024c 备注前端获取(资料价值较高,非无偿)
[外链图片转存中…(img-8EhfXlKs-1711589644114)]
总结一下
面试前要精心做好准备,简历上写的知识点和原理都需要准备好,项目上多想想难点和亮点,这是面试时能和别人不一样的地方。
还有就是表现出自己的谦虚好学,以及对于未来持续进阶的规划,企业招人更偏爱稳定的人。
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
万事开头难,但是程序员这一条路坚持几年后发展空间还是非常大的,一切重在坚持。
为了帮助大家更好更高效的准备面试,特别整理了《前端工程师面试手册》电子稿文件。
前端面试题汇总
JavaScript
性能
linux
前端资料汇总
前端工程师岗位缺口一直很大,符合岗位要求的人越来越少,所以学习前端的小伙伴要注意了,一定要把技能学到扎实,做有含金量的项目,这样在找工作的时候无论遇到什么情况,问题都不会大。