webpack第一次

Posted melimeli

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了webpack第一次相关的知识,希望对你有一定的参考价值。

webpack

1.动手实践

1.1动手实践过程

1.首先使用node安装npm,去文件目录下面,

mkdir zdj 
cd zdj
mkdir webpack-test
cd webpack-test
nmp init   ---  下面会出现package.json文件
npm install webpack --save-dev ---安装webpack
为什么要使用npm init初始化项目

在node开发中使用npm init会生成一个pakeage.json文件,这个文件主要是用来记录这个项目的详细信息的,它会将我们在项目开发中所要用到的包,以及项目的详细信息等记录在这个项目中。方便在以后的版本迭代和项目移植的时候会更加的方便。也是防止在后期的项目维护中误删除了一个包导致的项目不能够正常运行。使用npm init初始化项目还有一个好处就是在进行项目传递的时候不需要将项目依赖包一起发送给对方,对方在接受到你的项目之后再执行npm install就可以将项目依赖全部下载到项目里。
#### - -save和- -save-dev

在使用node开发时, 我们在工程中用到的包必须是package.json中列出。
而dependencies和devDependencies是package.json中的两个属性. 我们要用的包在这两个属性中列出即可.
dependencies 列出的包用于生产环境
devDependencies 用于开发环境和测试环境

1.执行 npm i express --save则表示我想在生产环境中使用express, 同时, express的版本信息会被写入package.json中的dependencies属性中.

2而执行npm i express --save-dev 表示我想在开发和测试环境中使用. express的版本信息会被写入package.json中的devDependencies属性中.

3.--save可以简写为-S, --save-dev可以简写为-D.

4.npm install xxx: 安装项目到项目目录下,不会将模块依赖写入devDependencies或dependencies。

npm install -g xxx: -g的意思是将模块安装到全局,具体安装到磁盘哪个位置,要看 npm cinfig prefix的位置

npm install -save xxx:-save的意思是将模块安装到项目目录下,并在package文件的dependencies节点写入依赖。

npm install -save-dev xxx:-save-dev的意思是将模块安装到项目目录下,并在package文件的devDependencies节点写入依赖。

技术图片

1.2第一次打包

1.2.1 单独的js文件打包

去 webpack-test根目录下面新建一个文件hello.js,文件内容如下:

技术图片

function hello(str) {
    alert(str);
}

然后执行打包命令

webpack hello.js bundle.js

发现如下错误

技术图片

解决办法:这个错误需要全局安装webpack,webpack-cli,webpack-dev-server

webpack才可以正常打包,然后执行一下命令安装包

npm i webpack -g 
npm i webpack-cli -g 
npm i webpack-dev-server -g 

但是发现执行打包命令的时候出了一些问题

技术图片

这是因为,webpack 4以上的 命令变成了

webpack hello.js -o hello_bundle.js --mode development 

mode模式有开发者模式和生产模式,生产模式是乱码,开发模式代码就可以看懂的

技术图片

技术图片

看到上面的结果终于打包成功了,

1.2.2 js引用其他文件打包

再看看有文件引用情况下的打包

去 webpack-test根目录下面新建一个文件world.js,文件内容如下:

function world() {
    return {

    }
}

然后修改hello.js内容

require('./world.js')
function hello(str) {
    alert(str);
}

再次执行打包命令,看看结果,就会有2个文件被打包

技术图片

打包后生成的文件内容里面包含所有的引用文件

技术图片

1.2.3 css文件类型打包

去 webpack-test根目录下面新建一个文件style.css文件,文件内容如下:

html,body {
    padding: 0;
    margin: 0;
}

执行打包命令,发现报错了

技术图片

webpack天生不支持css类型的文件,需要提前安装loader才可以

npm install css-loader style-loader -g
webpack hello.js -o hello_bundle.js --mode development

修改hello.js内容,执行打包命令就成功了

require('./world.js')
require('style-loader!css-loader!./style.css') --定义css打包所依赖的loader
function hello(str) {
    alert(str);
}

技术图片

1.2.4 运行html文件

去 webpack-test根目录下面新建一个文件index.html文件,文件内容如下:

<!DOCTYPE html>
<html>
<head>
    <title>webpack test</title>
</head>
<boy>
<script type="text/javascript" src="hello_bundle.js">
</script>
</boy>
</html>

修改hello.js文件内容,如下面

require('./world.js')
require('css-loader!./style.css')
function hello(str) {
    alert(str);
}
hello("hello world");

执行打包命令,然后打开html文件

就可以正常运行hello.js里面的内容了

技术图片

修改css文件属性,可以更明显一点

html,body {
    padding: 0;
    margin: 0;
}
body {
    background-color: red;
}

然后打包运行,发现并没有生效,css要生效必须添加style-loader,修改hello.js内容,css-loader使webpack可以处理css文件,style-loader把css-loader处理完的文件新建一个style(css)标签插入到html中。重新打包运行发现css生效了

require('./world.js')
require('style-loader!css-loader!./style.css')
function hello(str) {
    alert(str);
}
hello("hello world");

1.2.5 利用webpack命令参数可以提交效率的方式

1.--module-bind参数

如果每次加入css文件都要加入这些loader是比较麻烦的,修改hello.js的内容里面的css的loader,有个webpack的参数叫做--module-bind,可以指定loader参数,如下所示的命令,也可以打包成功

require('./world.js')
require('./style.css')
function hello(str) {
    alert(str);
}
hello("hello world");
webpack hello.js -o hello_bundle.js --mode development --module-bind "css=style-loader!css-loader"

2.watch参数

每次修改文件内容,我们都要重新执行打包命令,可以给webpack添加watch参数来监听。执行下面命令,这样每次修改js和css文件内容的时候就不需要重新打包了

webpack hello.js -o hello_bundle.js --mode development --module-bind "css=style-loader!css-loader" --watch

3.看到打包过程的progress参数

webpack hello.js -o hello_bundle.js --mode development --module-bind "css=style-loader!css-loader" --progress

4.看到打包的模块--display--modules

webpack hello.js -o hello_bundle.js --mode development --module-bind "css=style-loader!css-loader" --display-modules

5.看到打包的原因 --display-reasons

webpack hello.js -o hello_bundle.js --mode development --module-bind "css=style-loader!css-loader" --display-modules --display-reasons

1.3 webpack基本配置

1.3.1 webpack配置文件

1.根据1.2中介绍的新建一个webpack项目,安装webpack,该项目的根目录下新增dist和src目录来存放文件。

在src目录下面新增script和style目录,在根目录下新增index.html文件,文件内容如下

<!DOCTYPE html>
<html>
<head>
    <title>webpack demo</title>
</head>
<boy>
    <script type="text/javascript" src="bundle.js"> 
    </script>
</boy>
</html>

在项目根目录下面新建webpack.config.js文件,文件内容如下

module.exports={
    entry: './src/script/main.js',
    output: {
        path:  __dirname+'/dist',
        filename: 'bundle.js'
    }
}

然后运行webpack命令即可打包了,因为会默认读取webpack.config.js配置文件。

可以测试将webpack.config.js文件重新命令,执行webpack命令会报错,一定要指定--config 参数。

webpack hello.js -o hello_bundle.js --config webpack.dev.config.js

1.3.2 webpack配置文件添加运行命令的参数

1.2中的webpack是添加了多个参数的,1.3.1中只运行了webpack命令即可打包了,怎么给这个命令添加参数呢?

在package.json文件的scripts{}里面添加如下代码既可订制webpack参数,如下所示

 "webpack": "webpack --config webpack.config.js  --progress --display-module --colors --display-reasons --mode development"

技术图片

然后运行npm run webpack命令,即可执行订制的webpack命令内容。

1.3.3 webpack配置文件中的entry和output new

在项目根目录的script目录-js目录下面新建文件a.js文件,文件内容写个空函数

修改webpack.config.js文件的entry内容,如下图所示:

module.exports={
    entry: ['./src/script/main.js','./src/script/a.js'],
    output: {
        path:  __dirname+'/dist',
        filename: 'bundle.js'
    }
}

然后运行npm run webpack命令

技术图片

查看命令结果显示,a.js和main.js被打包到同一个文件,是因为output的filename只有一个,这样会导致多个文件打包相互覆盖到同一个文件;要想解决这个问题,要用 下面的方式,entry指定多个,output也动态指定

module.exports={
    entry:{
        main: './src/script/main.js',
        a: './src/script/a.js'
    },
    output: {
        path:  __dirname+'/dist',
        filename: '[name]-[chunkhash].js'
    }
}

name是指打包文件的名称,chunkhash可以理解为文件的版本号,是唯一的,当修改文件内容后,webpack打包生成的chunkhash也不相同。

执行webpack命令后会生成多个不同的文件,如下图所示:

技术图片

1.4 自动化生成项目中的html页面

1.4.1 入门:自动化生成项目中的html页面

如果按照1.3中的操作,每次修改文件,webpack生成的chunkhash都不相同,总不能每次都修改index.html中的打包文件名称来适配修改操作。如果每次修改后,能够自动修改引入的文件内容,就不用这么麻烦了。引入html-webpack-plugin 插件来解决这个问题,使用下面命令安装html-webpack-plugin 插件

npm install html-webpack-plugin --save-dev

然后修改webpack.config.js文件,增加对html-webpack-plugin的引用

var htmlWebpackPlugin=require('html-webpack-plugin');

module.exports={
    entry:{
        main: './src/script/main.js',
        a: './src/script/a.js'
    },
    output: {
        path:  __dirname+'/dist',
        filename: '[name]-[chunkhash].js'
    },
    plugins: [
        new htmlWebpackPlugin()
    ]
}

然后运行npm run webpack命令后,结果如下图所示,生成了一个html文件,但是这个文件是放在dist/js目录下面的,该html文件内容也是已经生成了带有chunkhash的内容。

技术图片

技术图片

现在有个问题是如何将插件生成的html文件和根目录下面的html建立联系呢???

可以通过给插件传递参数的方式来进行,修改webpack.config.js文件,如下图所示,将插件中的template指向根目录下面的html文件

var htmlWebpackPlugin=require('html-webpack-plugin');

module.exports={
    entry:{
        main: './src/script/main.js',
        a: './src/script/a.js'
    },
    output: {
        path:  __dirname+'/dist',
        filename: '[name]-[chunkhash].js'
    },
    plugins: [
        new htmlWebpackPlugin({
            template: "index.html"
        })
    ]
}

执行webpack命令后,发现生成的文件也被修改了,多了bundle.js文件

技术图片

此外,index.xhtml不用指定script文件的路径了,删掉即可,如下图所示

技术图片

1.4.2不同类型的文件生成不同的目录文件

1.4.1中有个问题,就是不同类型的文件生成到了同一个目录,同一个文件夹下面。不同类型的文件,我们希望生成到不同类型的文件夹中,怎么办呢?js文件希望生成一个文件夹,修改webpack.config.js文件,如下图所示

var htmlWebpackPlugin=require('html-webpack-plugin');

module.exports={
    entry:{
        main: './src/script/main.js',
        a: './src/script/a.js'
    },
    output: {
        path:  __dirname+'/dist',
        filename: 'js/[name]-[chunkhash].js' 
    },
    plugins: [
        new htmlWebpackPlugin({
           
            template: "index.html"
        })
    ]
}

在output里面的filename属性这里添加js,既可实现js类型的文件生成到js目录下面,执行webpack命令之后,效果如下图所示,js文件 和index.html已经分开

技术图片

同样的htmlWebpackPlugin插件也可以指定文件的名称--filename

var htmlWebpackPlugin=require('html-webpack-plugin');

module.exports={
    entry:{
        main: './src/script/main.js',
        a: './src/script/a.js'
    },
    output: {
        path:  __dirname+'/dist',
        filename: 'js/[name]-[chunkhash].js'
    },
    plugins: [
        new htmlWebpackPlugin({
            filename: 'index-[hash].html',
            template: "index.html"
        })
    ]
}

运行完命令后,如下图所示,已经生成了相应的文件。

技术图片

同样的htmlWebpackPlugin插件也可以指定wepack生成的文件放在head还是body里面,通过inject参数

inject: ‘head‘ 添加到htmlWebpackPlugin配置参数里即可。

1.4.3 打印htmlWebpackPlugin插件的配置参数

如下图代码所示,在webpack.config.js文件中配置了插件的参数

var htmlWebpackPlugin=require('html-webpack-plugin');

module.exports={
    entry:{
        main: './src/script/main.js',
        a: './src/script/a.js'
    },
    output: {
        path:  __dirname+'/dist',
        filename: 'js/[name]-[chunkhash].js'
    },
    plugins: [
        new htmlWebpackPlugin({
            filename: 'index.html',
            template: 'index.html',
            inject: 'head',
            title: 'webpack is good',
            date: new Date()
        })
    ]
}

然后在index.html中加入修改的参数,如果想知道htmlWebpackPlugin插件的参数,可以将参数打印出来看下

<!DOCTYPE html>
<html>
<head>
    <title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<title><%= htmlWebpackPlugin.options.date %></title>
<% for(var key in htmlWebpackPlugin) { %>
    <%= key %>
<% } %>
</body>
</html>

执行打包命令npm run webpack后,生成的html中如下图所示:

技术图片

这里有个问题,如果想知道htmlWebpackPlugin.files或者htmlWebpackPlugin.options里面的内容呢?可以对其进行遍历,但是htmlWebpackPlugin.options里面的内容有可能是对象或者数据,是个 json对象,利用JSON.stringify()方法将其字符串化,如下图的方法

<!DOCTYPE html>
<html>
<head>
    <title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<title><%= htmlWebpackPlugin.options.date %></title>
<% for(var key in htmlWebpackPlugin.files) { %>
    <%= key %>: <%= JSON.stringify(htmlWebpackPlugin.files[key]) %>
<% } %>

<% for(var key in htmlWebpackPlugin.options) { %>
    <%= key %>: <%= JSON.stringify(htmlWebpackPlugin.options[key]) %>
<% } %>

</body>
</html>

执行打包命令后,生成的文件如下图所示:

技术图片

从files的chunks属性中可以拿到打包生成的文件名称,options里项的含义可以从插件官网上查到详细信息。

通过上面的chunks信息,如果想在一部分js文件放在head标签里面,一部分js文件放在body标签里面,可以通过chunks信息的entry属性拿到打包生成的文件。如下图所示:

<!DOCTYPE html>
<html>
<head>
    <title><%= htmlWebpackPlugin.options.title %></title>
    <script type="text/javascript" src="<%=
    htmlWebpackPlugin.files.chunks.main.entry %>">

    </script>
</head>
<body>
<title><%= htmlWebpackPlugin.options.date %></title>
<script type="text/javascript" src="<%=
    htmlWebpackPlugin.files.chunks.a.entry %>">

</script>

</body>
</html>

注意将webpack.config.js文件中htmlWebpackPlugin的属性设为false,打包生成的文件如下图所示,这样就可以将不同的js文件引用到不同的地方。

技术图片

1.4.4 项目上线

如果项目要上线,那么怎么在线上访问我们的页面呢?这个时候在output属性中添加publicPath属性,可以实现这个需求,如下图所示添加publicPath,就可以在线上访问我们的页面了。

var htmlWebpackPlugin=require('html-webpack-plugin');

module.exports={
    entry:{
        main: './src/script/main.js',
        a: './src/script/a.js'
    },
    output: {
        path:  __dirname+'/dist',
        filename: 'js/[name]-[chunkhash].js',
        publicPath: 'http://cdn.com/'                   
    },
    plugins: [
        new htmlWebpackPlugin({
            filename: 'index.html',
            template: 'index.html',
            inject: 'false',
            title: 'webpack is good',
            date: new Date()
        })
    ]
}

查看打包生成的文件,如下图所示:

以上是关于webpack第一次的主要内容,如果未能解决你的问题,请参考以下文章

Vue报错:Uncaught TypeError: Cannot assign to read only property 'exports' of object 的解决方法(代码片段

Webpack第一天

如何使用webpack加载库源映射?

记一次webpack打包的问题

Sublime Text自定制代码片段(Code Snippets)

webpack第一节