安装
全局安装webpack
npm install -g webpack
当执行该操作后,便在C:\Users\你的用户名\AppData\Roaming\npm\node_modules创建了webpack文件夹,里面存储了刚刚全局安装的webpack模块。
我们在合适位置新建一个文件夹webpack-test,用于存放我们的项目。
命令行中定位到webpack-test文件夹下,输入以下命令进行项目的初始化:
npm init
这里,要求设置很多选项,可以按项目情况配置也可以不填直接回车。完成后,我们发现文件夹中增加了package.json文件,它用于保存关于项目的信息。
在根目录新建文件a.js,在命令行输入打包命令,将a.js打包成b.js
webpack a.js b.js
但会提示

因为新版本中CLI(命令行工具)已转移到单独的包webpack-cli中,需额外安装
本地安装webpack-cli
npm install webpack-cli -D
打包依旧报错

旧版本的webpack中,webpack指令要能在命令行中使用,需要全局安装webpack,而不是本地安装,因此这里的webpack-cli也应该是同理。
我们卸载本地安装的webpack-cli,全局安装webpack-cli:
npm uninstall webpack-cli
npm install -g webpack-cli
再次打包,依旧提示错误

这里提示我们存在的第一个问题是没有配置webpack的mode选项,默认有production和development两种模式可以设置,因此我们尝试设为development模式,在命令行输入
webpack –mode development
我们看到进行了打包并显示了Hash、Version、Time、Build at信息,表明已经可以打包。不过,仍然有错误提示
未找到入口模块
创建入口文件
webpack4.x以’./src/index.js’作为入口,我们需要在根目录创建src文件夹,将a.js移动到’./src’,并重命名为index.js。
现在如果我们再次执行
webpack index.js b.js
会提示can.t resolve相关的错误。
原因是,webpack4.x的打包已经不能用webpack 文件a 文件b的方式,而是直接运行webpack –mode development或者webpack –mode production,这样便会默认进行打包,入口文件是’./src/index.js’,输出路径是’./dist/main.js’,其中src目录即index.js文件需要手动创建,而dist目录及main.js会自动生成。
因此我们不再按webpack 文件a 文件b的方式运行webpack指令,而是直接运行
webpack –mode development
或者
webpack –mode production
这样便能够实现将’./src/index.js’打包成’./dist/main.js’。
不过每次都要输入这个命令,非常麻烦,我们在package.json中scripts中加入两个成员:
"dev":"webpack --mode development",
"build":"webpack --mode production"
以后我们只需要在命令行执行npm run dev便相当于执行webpack –mode development,执行npm run build便相当于执行webpack –mode production。
可以看到根目录下生成了dist目录,并且dist目录下生成了main.js文件,main.js文件已经打包了src目录下index.js文件的代码。
配置其他参数
我们如果需要配置webpack指令的其他参数,只需要在webpack –mode production/development后加上其他参数即可,如:
webpack –mode development –watch –progress –display-modules –colors –display-reasons
当然,这也可以写入package.json的scripts之中。
在根目录新建webpack.config.js
const config = {
entry: {
home: "./src/home.js",
about: "./src/about.js",
contact: "./src/contact.js"
},
output: {
filename: '[name].js',
path: __dirname + '/dist'
}
};
module.exports = config;
上面是最简单的多页面输入输出配置
动态添加入口文件:
var glob = require('glob');
var webpackConfig = {
entry:{}
};
// 获取指定路径下的入口文件
function getEntries(globPath) {
var files = glob.sync(globPath),
entries = {};
files.forEach(function(filepath) {
var split = filepath.split('/');
var name = split[1].split('.')[0];
//取src/a.js的a作为name
entries[name] = './' + filepath;
});
return entries;
}
var entries = getEntries('src/*');
Object.keys(entries).forEach(function(name) {
// 每个页面生成一个entry,如果需要HotUpdate,在这里修改entry
webpackConfig.entry[name] = entries[name];
})
module.exports = webpackConfig;
上面webpackConfig中还有module、plugins等属性
比如
module: {
rules: [
{ test: /\.css$/, use: ['style-loader', 'css-loader'] }
]
}
及style和css加载
还有
plugins:[]
然后可以在最外层引用插件var HtmlWebpackPlugin = require(‘html-webpack-plugin’);
使用
Object.keys(entries).forEach(function(name) {
// 每个页面生成一个entry,如果需要HotUpdate,在这里修改entry
webpackConfig.entry[name] = entries[name];
// 每个页面生成一个html
var plugin = new HtmlWebpackPlugin({
// 生成出来的html文件名
filename: name + '.[hash].html',//name + '.[hash].html',
// 每个html的模版,这里多个页面使用同一个模版
template: './src/a.html',
// 自动将引用插入html
inject: true,
hash: true, //为静态资源生成hash值
// 每个html引用的js模块,也可以在这里加上vendor等公用模块
chunks: [name],
minify: { //压缩HTML文件
removeComments: true, //移除HTML中的注释
collapseWhitespace: false //删除空白符与换行符
}
});
webpackConfig.plugins.push(plugin);
})
如果入口文件引用了模块a和模块b,而模块b依赖模块a,直接按先后顺序加载模块a和b无效,需要在b中也引入模块a
如果入口文件和模块b都需要模块a,两个文件都引入了模块a,打包后模块a被打包进文件(比如k.js),根据测试,k.js中好像只会打包一次模块a
如果希望只在入口文件引入一次a.js,而b中不再引入也可以使用,可用expose-loader[推荐使用],把公共文件设置为全局,比如bootstrap只在jq为全局时可以使用,就可以用这个方法,使用方法
import $ from 'expose-loader?$!./jquery.min.js'
//格式 import 名字 from 'expose-loader? libraryName!./file.js'
或者在webpack.config.js的module.rules中加入
{
test: require.resolve('./src/jquery.min.js'),
use: [{
loader: 'expose-loader',
options: 'jQuery'
},{
loader: 'expose-loader',
options: '$'
}]
}
//然后入口文件中普通引入:
import $ from './jquery.min.js'
//如果是npm下载的jQ,上面不需要路径,直接写’ jquery’即可
其他方法:
1.在webpack中添加插件ProvidePlugin[不推荐使用,因为没把jq放在全局,一些插件还是无法使用]
plugins: [
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery"
}),
]
// $函数会自动添加到当前模块的上下文,无需显示声明
问题是依旧没有全局的$函数,所以导入插件依旧会失败,并且如果有eslint这样的preLoads,调用语句也难以通过语法校验(因为没有声明$就直接使用)
2.包装jquery[推荐使用]
//创建一个jq的包装文件jquery-vendor.js
//包装jq,把他放在全局
import $ from ./jquery.min.js';
window.$ = $;
window.jQuery = $;
export default $;
//然后在入口文件中,不引用jq而是引用包装文件
import $ from './jquery-vendor.js'
林秀栋的技术博客