webpack stepped pit

operating efficiency

  • If the project is a multi-entry configuration, local development phase does not need to have all run every time
  • You can get to run a command line parameter determines which pages to run, speed
  • process.env.npm_config_argv or use yargs this package npm get command-line parameters passed
      
      
1
2
3
4
5
6
7
      
      
var scriptArg = process.env.npm_config_argv && JSON.parse(process.env.npm_config_argv);
var targetDir = scriptArg && scriptArg.original[ 2] && scriptArg.original[ 2].substr( 1) || '';
var js = glob.sync( './' + (targetDir || '**') + '/*.js').reduce( function (prev, curr) {
prev[curr.slice( 6, -3)] = [ './' + curr.substr( 6)];
return prev;
}, {});
      
      
1
2
3
4
5
6
7
      
      
var argv = require( 'yargs').argv;
var list = argv._[ 0] || '*';
var js = glob.sync( './' + list + '/*.js').reduce( function (prev, curr) {
prev[curr.slice( 6, -3)] = [curr];
return prev;
}, {});
  • process.env.npm_config_argv:在使用yarn run xxx的时候不能获取到参数,在使用npm run xxx的时候可以获取到
  • yargs这个包是都可以获取到的

路径问题

  • 问题描述:在上线和测试环境下代码发到cdn上,静态资源和页面地址不在一处,需要配置不同的前缀地址,才能引入线上script
  • 通过output -> publicPath 根据不同的环境变量变更path路径,解决加载问题
      
      
1
2
3
4
5
6
7
8
9
10
      
      
output: {
path: path.resolve( './build'),
filename: '[name].js',
publicPath: env === 'development'
? '/' : (
env === 'production'
? '//xxx.production.com/'
: '//xxx.test.com/'
)
}

htmlPlugin

普通配置

      
      
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
      
      
var htmlFiles = glob.sync( './**/*.html');
var html = htmlFiles.map( function (item) {
console.log(item.substr( 6));
return new HtmlWebpackPlugin({
data: {
build: true
},
filename: item.substr( 6),
template: 'ejs-compiled!' + item,
inject: false,
minify: {
removeComments: true,
collapseWhitespace: true,
preserveLineBreaks: true,
collapseInlineTagWhitespace: true,
collapseBooleanAttributes: true,
removeRedundantAttributes: true,
useShortDoctype: true,
caseSensitive: true,
minifyJS: true,
minifyCSS: true,
quoteCharacter: '"'
}
});
});
  • 把html 连接到webpack的plugin属性上(concat)一个配置只能针对一个文件
  • data的内容,可以在template里获取到然后做相应的改动
  • filename:输出html的名称,可以带路径
  • template: 模板名称及使用什么编译器 ejs-compiled可以使用ejs语法
  • inject:是否把所有静态资源自动添加到html里,这里不使用,目前的模板配置是直接引入了入口的文件,后面在回调里添加hash实现,下图是模板文件:
      
      
1
2
3
4
5
6
7
8
9
10
11
12
      
      
<!DOCTYPE html>
<html lang="en">
<head>
<%- include ../header.html -%>
<title></title>
<meta http-equiv="Cache-Control" content="no-cache">
</head>
<body>
<div id="mount"></div>
<script src="./xxx.js" defer></script>
</body>
</html>
  • 可以使用ejs的语法
  • minify:压缩模板配置
    • removeComments:删除注释
    • collapseWhitespace:删除多余的空格
    • preserveLineBreaks:保留每个标签tag的换行符
    • collapseInlineTagWhitespace:不保留行内元素两边的空格
    • collapseBooleanAttributes:使input的一些的布尔值的属性合并,不写等于了,例如:disabled
    • removeRedundantAttributes:删除多余的标签,例如没有赋值的style,class等
    • useShortDoctype:替换成较短的html5 doctype
    • caseSensitive:区分大小写的方式处理自定义标签
    • minifyJS:行内scripts标签,或者attribute里的是否压缩
    • minifyCSS:行内style标签,或者attribute里的是否压缩
    • quoteCharacter:对于attribute用什么符号

plugin完成后的一些操作

      
      
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
      
      
function () {
this.plugin('done', function (stats) {
var replaceInFile = function (filePath, toReplace, replacement) {
var str = fs.readFileSync(filePath, 'utf8');
var out = str.replace(toReplace, replacement);
fs.writeFileSync(filePath, out);
};
htmlFiles.map(function (item) {
replaceInFile(path.join(config.build.assetsRoot, item.substr(6)),
/(src|href)="([/w.]+.(js|css))"/g,
function ($0, $1, $2) {
var file = $2.split('.');
file.splice(-1, 0, stats.hash);
file = file.join('.');
return $1 + '="' + file + '"';
}
);
});
});
}

sass-loader

设置import相对路径,不过最后引用的时候用~开头,node_modules里的scss引用可以直接相对”~”引用

3.jpeg

https://github.com/webpack-contrib/sass-loader#imports

resolve

      
      
1
2
3
4
5
6
7
8
9
10
11
12
13
      
      
resolve: {
extensions: [ '', '.js', '.vue'],
fallback: [path.join(__dirname, '../node_modules')],
alias: {
'vue$': 'vue/dist/vue',
'scss': path.resolve(__dirname, '../src/modules/scss'),
'vue-directive': path.resolve(__dirname, '../src/modules/vue-directive'),
'request': path.resolve(__dirname, '../src/modules/request'),
'common': path.resolve(__dirname, '../src/modules/common'),
'vue-component': path.resolve(__dirname, '../src/modules/vue-component'),
'vue-fragment': path.resolve(__dirname, '../src/modules/vue-fragment')
}
}
  • extensions:扩展名
  • fallback:
  • alias:别名,具体定义一个别名的路径,方便引入modules
7.jpeg

webpack2把root,fallback迁移到了modules的配置里,告诉webpack解析的搜索路径
Explicit is better than implicit
alias清晰的比modules的好,效率??

配置代理

  • 背景:本地开发嵌套iframe的页面的时候,两个项目的端口号不统一,导致iframe同源策略不允许互相操作跳转
  • 解决:配置到同一端口号的域名上。“devServer.proxy”
      
      
1
2
3
4
5
6
7
8
9
10
11
12
13
14
      
      
devServer: {
host: 'localhost',
port: 8080,
historyApiFallback: true,
inline: true,
hot: true,
proxy: {
'/pages': 'http://localhost:8899'
},
stats: {
children: false,
chunks: false
}
}

注意点

  1. 路径是否正确,publicPath,path,如果是相对路径相对哪里,最好配置成path.resolve(__dirname, xxx)的形式
  2. If you are using someone else much better Configuration files, check for duplicate loader, loader configuration of multiple repeats of problems that may arise, tantamount module parses twice, will complain
  3. In the case of split module, you must configure publicPath, the address determining module loaded asynchronously

Original: Big Box  webpack stepped pit


Guess you like

Origin www.cnblogs.com/petewell/p/11607133.html