css 对现有PHP和JS项目使用Webpack

lb3vh1jj  于 2022-12-24  发布在  PHP
关注(0)|答案(2)|浏览(120)

我有一个现有的PHP项目,其中包含jquery和bootstrap,没有使用任何前端框架。
我正在尝试使用webpack模块捆绑器来为我的项目资源创建一个单一的入口点,用node js包管理器管理js依赖项,运行minify js css任务,图像调整大小......等等,并改善加载单个页面所需的浏览器加载时间。
我偶然发现了webpack教程,并安装了它和它的dev-server,但问题是,我无法理解我将如何转换所有当前项目中的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>

请帮助我理解此处的概念以及如何成功完成此迁移?

sz81bmfz

sz81bmfz1#

首先,回答你的小问题:

  • 不,你不应该通过webpack开发服务器运行PHP应用程序。在下面的 * 实时重新加载 * 一节中解释。
  • 不,你不需要重写你的资产。也许吧。参见下面的 * CSS * 和 * 边缘案例 * 部分。
  • 免责声明:* 我只回答你问题的一小部分。它的范围太广了,不能用一个StackOverflow的答案来回答。

我只会联系

  • 为webpack设置开发和生产环境
  • 绑定您的第一个JavaScript

这会给你打下基础。
我还将提到一些您可能希望根据参考资料添加和链接以通读的内容。
那我们走吧

要求

我假设您已经在计算机上安装了Node.js和npm,并且大致知道如何使用它们。
我还假设您已经安装了webpackwebpack-cli作为项目的(开发)依赖项(不仅仅是全局):

npm install --save-dev webpack webpack-cli
    • 更新:**此答案的早期版本不需要安装webpack-cli。自版本4(2018年2月)起,webpack的CLI位于其自己的软件包中,因此需要额外的软件包。

设置开发和生产工作流程

你通常希望在开发中做一些不同于生产中的事情(在生产中缩小,在开发中实时重载,...)
为了实现这一点,我们需要拆分配置文件。

准备目录结构

让我们同意忽略你的问题中的webpack配置。我们将从头开始,我们将不得不改变几乎所有的东西。
首先,在你的项目根目录下创建一个build文件夹,因为我们不想用配置文件污染你的项目根目录,所以构建相关的东西会放在那里(你可以随意给这个文件夹起不同的名字,但是在本教程中要记住这个名字)。
在该文件夹中创建config.base.jsconfig.production.jsconfig.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环境,反之亦然。
这个命令使用起来相当笨拙,但不用担心,我们稍后会解决这个问题。

创建一些帮助文件

有些信息我们需要集中起来,使它们更容易交换。文件路径就是这样一个东西。所以让我们把它们提取出来。
在您的build文件夹中创建一个paths.js,并让它导出一些我们稍后要使用的路径:

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 devnpm run prod运行构建链-这更容易记忆,键入速度更快。
......当然,只要有什么东西要建。

捆绑JavaScript

好吧,到目前为止,这实际上是一个相当大的工作量,没有取得太多的成果。
让我们从更令人兴奋的开始:我们将定义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
  }
}

创建JavaScript文件

上述配置要求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 '<script>标签将它包含到你的标记中。
祝贺您,您已经获得了一个可以正常工作的webpack设置!

潜得更深

这个迷你教程只是触及了你能用webpack做什么的表面。它为你的配置提供了一个相当坚实的基础,你现在可以用你需要的任何东西来填充。而这实际上会是相当多的东西。
我将列出一些您可能希望增强的内容,并提供一些链接供您通读。

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来访问生成的文件名。
阅读详情:

  • Immutable Caching介绍如何永久缓存您的包
  • webpack文档-chunkhash,介绍如何使用散列丰富捆绑包文件名
  • webpack-manifest-plugin,了解如何生成包含当前包的文件名的manifest.json

穿越

如果你想在你的网站的JavaScript中使用现代的ES2015代码(并且目标是非常青浏览器),你会想把它们转化为常规的ES5(如果"ES2015"这个词对你没有任何意义,你很可能没有使用它,可以忽略这一段)。
阅读更多:babel-loader – A loader that runs Babel on your scripts

CSS

有网页包加载器的CSS。和Sass。和PostCSS。无论你需要什么。
由于您可能不打算通过<script>标记包含CSS,因此请了解 * Extract Text Plugin * 以生成实际的.css文件。

    • 更新:****Extract Text Plugin * 非常成熟。然而,它实际上是一种黑客攻击:它生成.css文件,即使webpack只知道JavaScript作为其目标语言。

然而,从webpack4开始,这就不再是真的了。现在有一个系统可以定义任意的模块类型,包括CSS。
长话短说:预计webpack中的原生CSS支持将很快取代 * Extract Text Plugin *。

提示:路径

我会提到这一点,因为这是一个真正的痛点,直到我意识到如何webpack在这里工作:
请注意,webpack将识别您的url(...)语句,并尝试 * 相对于您的源文件 * 解析它们。
这意味着,您的源文件public/css/main.css

body {
  background: url('../img/bg.jpg');
}

如果输出路径为public/dist/css/bundle.css,则将转换为:

body {
  background: url('../../img/bg.jpg');
}

阅读详情:

缩小

    • 更新:**自webpack 4于2018年2月发布以来,此部分已相当过时。将新的mode选项设置为"production"将自动应用JavaScript缩小。

webpack有一个Terser插件来缩小你的JavaScript。缩小CSS是上面提到的css-loader插件已经内置的一个特性。
阅读更多:Terser webpack Plugin

图像优化

webpack是一个捆绑器,而不是任务运行器。因此,图像优化不是一个真正的webpack任务。你可能会更好地使用一个实际的任务运行器或只是定义一些npm脚本。
这并不意味着webpack不能做到这一点。几乎所有的东西都有插件。
阅读详情:

实时重新加载

你的问题有一个非常简单的原因:webpackdev服务器只是一个简单的Node.js服务器,只提供静态文件。
对于您的情况,webpack-dev-server可能是一个完全错误的工具。请尝试webpack-livereload-plugin,而不是一个实时重载器,您可以通过<script>标记包含它。
阅读更多:webpack-livereload-plugin

源Map

    • 更新:**自webpack 4(2018年2月发布)起,当新的mode选项设置为"development"时,源Map将自动生成。

无论如何,使用源代码Map,它们会让你的包工作变得容易得多,你会想哭的。
阅读更多:Webpack文档-源Map

边缘案例

通常,所有使用webpack处理的现有脚本都应该运行良好。
我现在想到的唯一例外是关于全球实体。
看下面的代码:

function myFunc () {
  console.log('I exist!')
}

这段代码在一个普通的JavaScript文件中可以使myFunc在你的JS代码中随处可用,但是由于webpack包代码被 Package 在回调函数中(因此离开了全局范围),所以不再有任何对该函数的访问。

第三方库应该不是问题,它们通常直接将全局变量赋值给window对象,但是如果您已经在项目中编写了JS代码,则应该注意这一点。

自动化!

您可能希望尽可能多地实现工作流程的自动化。
考虑在推拉之前/之后通过git钩子运行npm run prod

w51jfk4q

w51jfk4q2#

基于现有的vue模板和@Loilo的回答,我制作了一个可以用vue-cli安装的vue模板,这个模板可以帮助你快速启动一个可以扩展或集成到现有环境中的vue应用程序。

npm install -g vue-cli
vue init delcon/webpack-simple my-project
cd my-project
npm install

开发人员监视:

这个模板有一个额外的run devwatch选项来监视文件的变化,而不是使用webpack-dev-server。这使得它可以用于任何现有的webserver环境。

npm run devwatch

偏差:

要使用默认webpack-dev-server运行它,请删除index.html中的<script src="http://localhost:35729/livereload.js"></script>

npm run dev

内部版本:

要生成用于生产的项目:

npm run build

相关问题