我有一个带有jquery和bootstrap的现有PHP项目,没有使用任何前端框架。
我正在尝试使用webpack模块bundler为我的项目资源创建一个入口点,使用node js package manager管理js依赖项,运行minify js css,image re-size等等任务。并改善加载单个页面所需的浏览器加载时间。
我遇到了webpack教程,并安装了它并安装了它的开发服务器,但问题是我无法理解如何在项目中转换所有当前的js脚本和css链接(我在哪里)有很多jquery和CSS库用于在项目中提供多个功能)来使用webpack。
我是否必须以适合webpack的方式重写所有JS和CSS文件?如何成功迁移?
此外,我无法在webpack dev-server上运行我当前的php应用程序,它是否意味着首先在那里运行?它只列出了项目目录。
我创建了一个测试index.js
文件并使用了以下webpack配置:
var path = require('path');
var webpack = require('webpack');
module.exports =
{
entry: [
'./public/js/index.js',
'webpack/hot/dev-server',
'webpack-dev-server/client?http://localhost:8080'
],
plugins: [
new webpack.HotModuleReplacementPlugin()
],
output: {
path: path.join(__dirname, "public/dist/js"),
publicPath : "http://localhost:8080/my_proj/public/dist/js",
filename: "bundle.js"
}
};
我将bundle.js
添加到我的脚本加载中仅用于测试,如下所示,希望应用程序将在webpack dev-server上运行:
<script type="text/javascript" src="public/dist/js/bundle.js"></script>
<script type="text/javascript" src="public/js/jquery.min.js"></script>
<script type="text/javascript" src="public/js/jquery.migrate.js"></script>
<script type="text/javascript" src="public/js/jquery.bxslider.min.js"></script>
<script type="text/javascript" src="public/js/jquery.appear.js"></script>
<script type="text/javascript" src="public/js/jquery.countTo.js"></script>
<script type="text/javascript" src="public/js/bootstrap.js"></script>
请帮助我理解此处的概念以及如何成功完成此迁移?
答案 0 :(得分:121)
首先,回答你的小问题:
免责声明:我只会提出您问题的一小部分内容。它的范围太宽泛,无法包含在一个StackOverflow答案中。
我只会与
取得联系应该为你奠定基础。
我还会提到一些您可能想要添加的内容,并根据资源进行链接以便阅读。
所以,让我们走吧。
我假设你的机器上安装了Node.js和npm,并且大致知道如何使用它们。
我还假设您已将webpack
和webpack-cli
安装为项目的(dev)依赖项(不仅仅是全局):
npm install --save-dev webpack webpack-cli
更新:此答案的早期版本不需要安装
webpack-cli
。从版本4(2018年2月)开始,webpack的CLI位于自己的包中,因此需要额外的包。
您通常希望在开发中使用与生产中不同的东西(在生产中缩小,在开发中实时重新加载......)
为实现这一目标,我们希望拆分配置文件。
我们同意忽略您问题中的webpack配置。我们将从头开始,无论如何我们都必须改变一切。
首先,在项目根目录中创建一个build
文件夹。与构建相关的东西会去那里,因为我们不想用配置文件污染项目的根文件夹。 (您可以自由地以不同的方式命名此文件夹,但在本教程中会对此进行跟踪。)
在该文件夹中创建config.base.js
,config.production.js
和config.development.js
文件。
很好,我们现在有两个构建链的配置文件。虽然配置仍然是空的,所以现在让我们用一些基本逻辑填充它们。
webpack-merge
但首先,我们需要安装webpack-merge
。
npm install --save-dev webpack-merge
这个包允许我们深度合并多个webpack配置。我们希望根据当前环境使用它来创建webpack配置。
现在调整build/config.base.js
:
module.exports = {
// We'll place webpack configuration for all environments here
}
该文件显然现在只是导出一个空对象,但我们需要执行以下步骤。
将此代码放入build/config.production.js
:
const merge = require('webpack-merge')
module.exports = merge(require('./config.base.js'), {
mode: 'production'
// We'll place webpack configuration for production environment here
})
几乎相同的代码会进入您的build/config.development.js
:
const merge = require('webpack-merge')
module.exports = merge(require('./config.base.js'), {
mode: 'development',
watch: true
// All webpack configuration for development environment will go here
})
我认为这非常直观:
使用带有config.development.js
配置的webpack将获取通用配置并合并其自己的配置声明。
更新:上述配置文件中的
mode
选项已添加到webpack 4(2018年2月发布)中。它为开发和生产包设置了a bunch of sensible defaults。
现在,从命令行运行该过程将如下所示:
npx webpack --config build/config.development.js
# If the above doesn't work, you probably have an older version of npm (< 5.1) installed
# While npx is a really great tool, you can of course still call the path of the webpack executable manually:
node_modules/.bin/webpack --config build/config.development.js
...反之亦然production
环境。
这个命令使用起来相当笨拙,但不用担心,我们稍后会解决这个问题。
我们希望集中信息以使其易于交换。文件路径就是这样的东西。所以让我们提取它们。
在paths.js
文件夹中创建build
并让它导出我们稍后想要使用的路径:
const path = require('path')
// I'm really just guessing your project's folder structure from reading your question,
// you might want to adjust this whole section
module.exports = {
// The base path of your source files, especially of your index.js
SRC: path.resolve(__dirname, '..', 'public'),
// The path to put the generated bundle(s)
DIST: path.resolve(__dirname, '..', 'public', 'dist'),
/*
This is your public path.
If you're running your app at http://example.com and I got your DIST folder right,
it'll simply be "/dist".
But if you're running it locally at http://localhost/my/app, it will be "/my/app/dist".
That means you should probably *not* hardcode that path here but write it to a
machine-related config file. (If you don't already have something like that,
google for "dotenv" or something similar.)
*/
ASSETS: '/dist'
}
如上所述,我们可以在技术上以development
模式运行我们的构建链,如下所示:
npx webpack --config build/config.development.js
虽然这是一个令人不安的冗长命令,所以让我们改变它。
通过npm
脚本运行构建过程更方便。每个环境为您的package.json
添加一个脚本,如下所示:
{
"scripts": {
"dev": "webpack --config build/config.development.js",
"prod": "webpack --config build/config.production.js"
}
}
现在,您可以使用npm run dev
resp运行构建链。 npm run prod
- 更容易记忆,输入速度更快。
......当然,只要有什么东西可以建立。
好的,到目前为止,这实际上是相当多的工作而没有达到太多。
让我们从更令人兴奋的事情开始:我们将定义一个JavaScript入口点。
将以下代码放入build/config.base.js
(完全替换现有代码):
const path = require('path')
const { SRC, DIST, ASSETS } = require('./paths')
module.exports = {
entry: {
scripts: path.resolve(SRC, 'js', 'index.js')
},
output: {
// Put all the bundled stuff in your dist folder
path: DIST,
// Our single entry point from above will be named "scripts.js"
filename: '[name].js',
// The output path as seen from the domain we're visiting in the browser
publicPath: ASSETS
}
}
上述配置要求index.js
生成SRC/js
文件夹(如build/paths.js
中所定义)。
让我们使用以下内容创建该文件:
import './jquery.min.js'
import './jquery.migrate.js'
import './jquery.bxslider.min.js'
import './jquery.appear.js'
import './jquery.countTo.js'
import './bootstrap.js'
如您所见,index.js
只会导入您要使用的所有文件。
如果你现在运行
npm run prod
从您的终端,将在scripts.js
文件夹中创建DIST
文件。你可以用一个简单的ol&#39;将它包含在你的标记中。 <script>
代码。
恭喜,您已经开始使用网络包了!
这个迷你教程真的只是简单地说明了你可以用webpack做什么。它为您的配置提供了坚实的基础,您现在可以根据需要填写。这实际上将是很多东西。
我会列出一些您可能想要增强的内容,并提供一些可供阅读的链接。
如果您想使用webpack,如果您不了解其基本概念,则可能很难这样做。 Juho Vepsäläinen为webpack入门创建了一个很好的指南,这对我帮助很大。他也是webpack的核心贡献者,所以你可以确定他知道他在说什么。
特别是加载器是您真正需要知道的概念。
此列表中的许多提示也在那里解释。
了解详情:SurviveJS – webpack tutorial
这就是名称所说的:您可能不想将所有JavaScript打包成一个庞大的输出文件。
这是webpack所做的工作,可以拆分您在应用程序的某些页面上只需要的部分内容。
此外,根据您处理项目JavaScript的频率,最好从捆绑包中拆分第三方代码以用于缓存目的。
了解详情:webpack Documentation – Code Splitting
您可能希望通过向捆绑文件名添加哈希来增强站点的缓存行为,这取决于其内容。这将创建(例如)script.31aa1d3cad014475a618.js
而不是scripts.js
。
然后可以无限期缓存该文件,因为只要其内容发生更改,文件名也会更改。
然后,您的PHP代码可能会使用webpack-manifest-plugin
来访问生成的文件名。
了解更多:
chunkhash
关于如何使用哈希来丰富您的包文件名webpack-manifest-plugin
有关如何生成包含当前捆绑包文件名的manifest.json
如果您想在您网站的JavaScript中使用现代ES2015代码(并且定位非常青网浏览器),您需要将它们转换为常规ES5。 (如果术语&#34; ES2015&#34;对您没有任何意义,您很可能不会使用它并且可以忽略此段。)
了解详情:babel-loader
– A loader that runs Babel on your scripts
有CSS的webpack加载器。和萨斯。和PostCSS。无论你需要什么。
由于您可能不打算通过<script>
标记添加CSS,因此请了解 Extract Text Plugin 以生成实际的.css
文件。< / p>
提示:路径更新: 提取文字插件已经建立。但是,它实际上是一种黑客攻击:即使webpack只知道JavaScript作为目标语言,它也会生成
.css
个文件。然而,从webpack 4开始,这已不再适用。现在有一个定义任意模块类型的系统,包括CSS。
长话短说:Expect native CSS support in webpack to replace Extract Text Plugin some time soon。
我会提到这一点,因为这对我来说是一个真正的痛点,直到我意识到webpack如何在这里工作:
请注意,webpack会识别您的url(...)
语句,并尝试相对于您的源文件解析 。
这意味着,您的源文件public/css/main.css
:
body {
background: url('../img/bg.jpg');
}
如果您的输出路径为public/dist/css/bundle.css
,则会转换为:
body {
background: url('../../img/bg.jpg');
}
了解更多:
extract-text-webpack-plugin
更新:由于webpack 4于2018年2月发布,因此该部分已过时。将新
mode
选项设置为"production"
现在会自动应用JavaScript缩小。
有一个Terser插件可供webpack缩小您的JavaScript。缩小CSS是已经内置于上述css-loader
插件的功能。
webpack是一个捆绑器,而不是任务运行器。因此,图像优化不是真正的webpack任务。您可能最好使用实际的任务运行器或仅为此定义一些npm
脚本。
这并不意味着webpack无法做到这一点。几乎所有东西都有插件。
了解更多:
实时重新加载的问题有一个非常简单的原因:webpack dev服务器只是一个简单的Node.js服务器,只提供静态文件。
对于你而言,webpack-dev-server
可能是错误的工具。请尝试使用webpack-livereload-plugin
代替您可以通过<script>
代码添加的实时重新加载器。
了解详情:webpack-livereload-plugin
更新:从webpack 4(2018年2月发布)开始,当新的
mode
选项设置为"development"
时,会自动生成源地图。
一定要使用源地图。他们会让您更轻松地使用捆绑包来工作。
了解详情:webpack Documentation – Source Maps
通常,您使用webpack处理的所有现有脚本应该运行得很好。
现在我想到的唯一例外是关于全球实体。
请查看以下代码:
function myFunc () {
console.log('I exist!')
}
普通JavaScript文件中的此代码将使myFunc
在JS代码中随处可用。但是由于webpack包代码被包装在回调函数中(因此离开了全局范围),因此不再能够访问该函数。
第三方库不应该是一个问题,它们通常直接将它们的全局变量分配给window
对象,但如果您已经在项目中编写了JS代码,那么您应该知道这一点。
您希望自动化尽可能多的工作流程。
在推/拉之前,考虑通过git hook运行npm run prod
。
希望这有帮助。
答案 1 :(得分:0)
根据现有的vue-templates和@Loilo的回答,我制作了一个vue模板,您可以使用vue-cli
进行安装。此模板可以快速启动您可以扩展或集成到现有环境中的vue应用程序。
npm install -g vue-cli
vue init delcon/webpack-simple my-project
cd my-project
npm install
<强> devwatch:强>
此模板有一个额外的运行devwatch选项,用于监视文件更改而不是使用webpack-dev-server。这使它可用于任何现有的网络服务器环境。
npm run devwatch
<强> dev的:强>
使用默认的webpack-dev-server运行它,删除<script src="http://localhost:35729/livereload.js"></script>
中的index.html
:
npm run dev
<强>构建强>
构建生产项目:
npm run build