I'm trying to connect wiredep with my project, with no success. I have the bower_components and bower.json inside assets/, and the gruntfile.js in the root directory. Here's the relevant gruntfile:
wiredep: {
target: {
src: [
'grunt-test.html',
'application/views/inc/inc_scripts.php',
'application/views/inc/inc_head.php'
],
directory: 'assets/bower_components',
bowerJson: 'assets/bower.json',
fileTypes: {
php: {
block: /(([\s\t]*)<!--\s*bower:*(\S*)\s*-->)(\n|\r|.)*?(<!--\s*endbower\s*-->)/gi,
detect: {
js: /<script.*src=['"](.+)['"]>/gi,
css: /<link.*href=['"](.+)['"]/gi
},
replace: {
js: '<script src="{{filePath}}"></script>', // <-- Change this line
css: '<link rel="stylesheet" href="{{filePath}}" />'
}
},
html: {
block: /(([\s\t]*)<!--\s*bower:*(\S*)\s*-->)(\n|\r|.)*?(<!--\s*endbower\s*-->)/gi,
detect: {
js: /<script.*src=['"](.+)['"]>/gi,
css: /<link.*href=['"](.+)['"]/gi
},
replace: {
js: '<script src="{{filePath}}"></script>', // <-- Change this line
css: '<link rel="stylesheet" href="{{filePath}}" />'
}
}
}
}
}
Then I run grunt wiredep --verbose and get the following output:
Running "wiredep" task
Running "wiredep:target" (wiredep) task
Verifying property wiredep.target exists in config...OK
Files: grunt-test.html, application/views/inc/inc_scripts.php, application/views
/inc/inc_head.php
Verifying property wiredep.target.src exists in config...OK
Options: src=["grunt-test.html","application/views/inc/inc_scripts.php","application/views/inc/inc_head.php"], directory="assets/bower_components", bowerJson="a ssets/bower.json",fileTypes={"php":{"block":{},"detect":{"js":{},"css":{}},"replace":{"js":"<script src=\"{{filePath}}\"></script>","css":"<link rel=\"stylesheet\" href=\"{{filePath}}\" />"}},"html":{"block":{},"detect":{"js":{},"css":{}},"replace":{"js":"<script src=\"{{filePath}}\"></script>","css":"<link rel=\"stylesheet\" href=\"{{filePath}}\" />"}}}
Done, without errors.
But nothing happens. I've made sure that I'm using the right tags and even tried adding an HTML file (grunt-test.html) to make sure it's not a filetype thing, but I'm at a loss right now.
What do you guys see?
Thanks in advance.
Related
I am currently switching from webpack to vite.
Current status is, that build commands (yarn production) works for js and css using vite.
However, using the dev server, I receive an 404 message telling me, that the files weren't found - what did I miss?
Below is my code:
vite.config.js
export default ({ command }) => ({
base: command === 'serve' ? '' : '/build/',
publicDir: 'fake_dir_so_nothing_gets_copied',
build: {
manifest: true,
outDir: 'public/build',
rollupOptions: {
input: 'resources/js/app.js',
},
},
server: {
strictPort: true,
port: 3000
},
resolve: {
alias: {
'#': '/js',
}
}
});
helpers.php
<?php
use Illuminate\Support\Facades\Http;
use Illuminate\Support\HtmlString;
function vite_assets(): HtmlString
{
$devServerIsRunning = false;
if (app()->environment('local')) {
try {
Http::get("http://localhost:3000");
$devServerIsRunning = true;
} catch (Exception) {
}
}
if ($devServerIsRunning) {
return new HtmlString(<<<HTML
<script type="module" src="http://localhost:3000/#vite/client"></script>
<script type="module" src="http://localhost:3000/resources/js/app.js"></script>
HTML);
}
$manifest = json_decode(file_get_contents(
public_path('build/manifest.json')
), true);
return new HtmlString(<<<HTML
<script type="module" src="/build/{$manifest['resources/js/app.js']['file']}"></script>
<link rel="stylesheet" href="/build/{$manifest['resources/js/app.js']['css'][0]}">
HTML);
}
so I can finally embed {{ vite_assets() }} inside my blade layout
I recommend you to use: https://laravel-vite.dev/ when passing from webpack to vite, it worked perfect for me and took me like less than an hour.
......and I've no idea what the hell I'm doing. 😬
Okay let me explain I'm going back over a Wordpress course I did on Udemy where the now AWOL instructor implemented a automated workflow for us to use whereby anytime we typed PHP or JS the webpage would reload automatically, and it's working, actually it's working too fast for me. This time round for some reason it's driving me bonkers cos when I'm writing my code the page is recompiled before I can even finish typing a complete line of code! The webpage generates a parse error and I have to manually refresh the page when I'm done to clear the error as it doesn't get automatically refreshed due to the error, which sort of defeats the purpose of the automation.
The automated workflow was basically implemented by doing the following:
I've installed 2 files package.json & webpack.config.js into my theme
folder
Then I ran npm run devFast
Then by changing functions.php we got the WP theme to use the Node
generated assets. Node serves up all of the JavaScript and CSS within
one single bundled file, bundled.js
I've no idea where to start in asking for help with this so thought I'd start here. As I say any help with this would be appreciated even if you just signpost me. I'm also using Local by Flywheel to host the site locally and this has been a great tool.
If it helps my webpack file is ...
/*
SUPER IMPORTANT: This config assumes your theme folder is named
exactly 'fictional-university-theme' and that you have a folder
inside it named 'bundled-assets' - If you'd like to adapt this
config to work with your own custom folder structure and names
be sure to adjust the publicPath value on line #116. You do NOT
need to update any of the other publicPath settings in this file,
only the one on line #116.
*/
const currentTask = process.env.npm_lifecycle_event
const path = require("path")
const MiniCssExtractPlugin = require("mini-css-extract-plugin")
const { CleanWebpackPlugin } = require("clean-webpack-plugin")
const ManifestPlugin = require("webpack-manifest-plugin")
const fse = require("fs-extra")
const postCSSPlugins = [require("postcss-import"), require("postcss-mixins"), require("postcss-simple-vars"), require("postcss-nested"), require("postcss-hexrgba"), require("postcss-color-function"), require("autoprefixer")]
class RunAfterCompile {
apply(compiler) {
compiler.hooks.done.tap("Update functions.php", function () {
// update functions php here
const manifest = fse.readJsonSync("./bundled-assets/manifest.json")
fse.readFile("./functions.php", "utf8", function (err, data) {
if (err) {
console.log(err)
}
const scriptsRegEx = new RegExp("/bundled-assets/scripts.+?'", "g")
const vendorsRegEx = new RegExp("/bundled-assets/vendors.+?'", "g")
const cssRegEx = new RegExp("/bundled-assets/styles.+?'", "g")
let result = data.replace(scriptsRegEx, `/bundled-assets/${manifest["scripts.js"]}'`).replace(vendorsRegEx, `/bundled-assets/${manifest["vendors~scripts.js"]}'`).replace(cssRegEx, `/bundled-assets/${manifest["scripts.css"]}'`)
fse.writeFile("./functions.php", result, "utf8", function (err) {
if (err) return console.log(err)
})
})
})
}
}
let cssConfig = {
test: /\.css$/i,
use: ["css-loader?url=false", { loader: "postcss-loader", options: { plugins: postCSSPlugins } }]
}
let config = {
entry: {
scripts: "./js/scripts.js"
},
plugins: [],
module: {
rules: [
cssConfig,
{
test: /\.js$/,
exclude: /(node_modules)/,
use: {
loader: "babel-loader",
options: {
presets: ["#babel/preset-react", ["#babel/preset-env", { targets: { node: "12" } }]]
}
}
}
]
}
}
if (currentTask == "devFast") {
config.devtool = "source-map"
cssConfig.use.unshift("style-loader")
config.output = {
filename: "bundled.js",
publicPath: "http://localhost:3000/"
}
config.devServer = {
before: function (app, server) {
/*
If you want the browser to also perform a traditional refresh
after a save to a JS file you can modify the line directly
below this comment to look like this instead. I'm using this approach
instead of just disabling Hot Module Replacement beacuse this way our
CSS updates can still happen immediately without a page refresh.
If you're using a slower computer and the new bundle is not ready
by the time this is reloading the browser you can always just set the
"hot" property a few lines below this to false instead of true. That
will work on all computers and the only trade off is the browser will
perform a traditional refresh even for CSS changes as well.
*/
// server._watch(["./**/*.php", "./**/*.js"])
server._watch(["./**/*.php", "!./functions.php"])
},
public: "http://localhost:3000",
publicPath: "http://localhost:3000/",
disableHostCheck: true,
contentBase: path.join(__dirname),
contentBasePublicPath: "http://localhost:3000/",
hot: true,
port: 3000,
headers: {
"Access-Control-Allow-Origin": "*"
}
}
config.mode = "development"
}
if (currentTask == "build" || currentTask == "buildWatch") {
cssConfig.use.unshift(MiniCssExtractPlugin.loader)
postCSSPlugins.push(require("cssnano"))
config.output = {
publicPath: "/wp-content/themes/fictional-university-theme/bundled-assets/",
filename: "[name].[chunkhash].js",
chunkFilename: "[name].[chunkhash].js",
path: path.resolve(__dirname, "bundled-assets")
}
config.mode = "production"
config.optimization = {
splitChunks: { chunks: "all" }
}
config.plugins.push(new CleanWebpackPlugin(), new MiniCssExtractPlugin({ filename: "styles.[chunkhash].css" }), new ManifestPlugin({ publicPath: "" }), new RunAfterCompile())
}
module.exports = config
As already posted:
I should have said I'm using the auto-save feature in VS Code and to save my sanity I've turned this off which is doing the job. But is there another or better way?
When I upload the project to Heroku the icon of Semantic UI not show and I got net::ERR_ABORTED 404 (Not Found)
But in localhost, it works fine
I have checked the path in CSS file alls looks normal
webpack.mix.js
mix.scripts([
'node_modules/jquery/dist/jquery.js',
'node_modules/semantic-ui-css/semantic.min.js',
], 'public/js/app.js');
mix.sass('resources/sass/app.scss', 'public/css');
mix.setPublicPath('public');
mix.setResourceRoot('../');
app.scss
// Fonts
#import url('https://fonts.googleapis.com/css?family=Nunito');
// Variables
#import 'variables';
// Semantic
#import '~semantic-ui-css/semantic.min.css';
// Semantic ui icon
//#import '~semantic-ui-css/components/icon.min.css'; <-- I have try this not work !
Also, I add CSS file in the head like
<link href="{{ asset('css/app.css') }}" rel="stylesheet">
Do any suggestions please why this happened ??
I figured out the problem was from a vendor directory in the font folder, I thing Heroku ignore that folder (vendor) for some reason,
The path fonts/vendor/semantic-ui-css/themes/default generated automatically by mix So what I do is modify webpack-rules.js file placed in node_modules\laravel-mix\src\builder
rules.push({
// only include svg that doesn't have font in the path or file name by using negative lookahead
test: /(\.(png|jpe?g|gif|webp)$|^((?!font).)*\.svg$)/,
loaders: [
{
loader: 'file-loader',
options: {
name: path => {
if (!/node_modules|bower_components/.test(path)) {
return (
Config.fileLoaderDirs.images +
'/[name].[ext]?[hash]'
);
}
return (
Config.fileLoaderDirs.images +
'/' + //<--------------------- Remove vendor from image path
path
.replace(/\\/g, '/')
.replace(
/((.*(node_modules|bower_components))|images|image|img|assets)\//g,
''
) +
'?[hash]'
);
},
publicPath: Config.resourceRoot
}
},
{
loader: 'img-loader',
options: Config.imgLoaderOptions
}
]
});
// Add support for loading fonts.
rules.push({
test: /(\.(woff2?|ttf|eot|otf)$|font.*\.svg$)/,
loader: 'file-loader',
options: {
name: path => {
if (!/node_modules|bower_components/.test(path)) {
return Config.fileLoaderDirs.fonts + '/[name].[ext]?[hash]';
}
return (
Config.fileLoaderDirs.fonts +
'/' + //<------------------------- Remove vendo from font path
path
.replace(/\\/g, '/')
.replace(
/((.*(node_modules|bower_components))|fonts|font|assets)\//g,
''
) +
'?[hash]'
);
},
publicPath: Config.resourceRoot
}
});
After push project to Heroku all working fine.
If anyone has a better solution or know why the vendor directory make this issue please explain.
Thanks for all.
I want to achieve this using grunt
Goal
My main goal is to minify my index.php before placing them on my production server.
It's simple if I have 1 single index.html, but I don't.
Instead I have an index.php full with other .php files.
Each <?php ?> section is a block of HTML code.
index.php
<!DOCTYPE html>
<?php include '2015/layouts/ie.php'; ?>
<head>
<?php include '2015/layouts/meta.php'; ?>
<title>Title</title>
<?php include '2015/layouts/link.php'; ?>
<?php include '2015/layouts/style.php'; ?>
<?php include '2015/layouts/ie9.php'; ?>
</head>
<body >
<span id="web">
<?php include '2015/layouts/nav-bar.php'; ?>
<?php include '2015/layouts/welcome-sign.php'; ?>
<?php include '2015/layouts/profile.php'; ?>
<?php include '2015/layouts/skill.php'; ?>
<?php include '2015/layouts/education.php'; ?>
<?php include '2015/layouts/experience.php'; ?>
<?php include '2015/layouts/portfolio.php'; ?>
<?php include '2015/layouts/contact.php'; ?>
<?php include '2015/layouts/script.php'; ?>
</span>
<span id="print" style="display: none;" ><img src="2015/img/image.png" width="90%"></span>
</body>
</html>
Lastly
I'm wondering what is the most efficient way to concatenate all my .php files into one php file, and minify it.
I prefer to achieve this using grunt, but if someone might have other suggestion on a better solution please feel free to suggest me.
I accomplished this in 2 simple steps:
concat all the php file into 1 long php file
minify that long php file
Step1
using : grunt-contrib-concat
concat: {
php: {
src: [
'2015/layouts/ie.php',
'2015/layouts/meta.php',
'2015/layouts/link.php',
'2015/layouts/style.php',
'2015/layouts/ie9.php',
'2015/layouts/nav-bar.php',
'2015/layouts/welcome-sign.php',
'2015/layouts/profile.php',
'2015/layouts/skill.php',
'2015/layouts/education.php',
'2015/layouts/experience.php',
'2015/layouts/portfolio.php',
'2015/layouts/contact.php',
'2015/layouts/script.php'
],
dest: 'dist/php/concat.php'
}
}
Step2
using : grunt-contrib-htmlmin
htmlmin: {
dist: {
options: {
removeComments: true,
collapseWhitespace: true
},
tasks: ['clean:php'],
files: {
'index.php': 'dist/php/concat.php',
}
}
}
Final grunt.initConfig() should look like
grunt.initConfig({
concat: {
php: {
src: [
'2015/layouts/ie.php',
'2015/layouts/meta.php',
'2015/layouts/link.php',
'2015/layouts/style.php',
'2015/layouts/ie9.php',
'2015/layouts/nav-bar.php',
'2015/layouts/welcome-sign.php',
'2015/layouts/profile.php',
'2015/layouts/skill.php',
'2015/layouts/education.php',
'2015/layouts/experience.php',
'2015/layouts/portfolio.php',
'2015/layouts/contact.php',
'2015/layouts/script.php'
],
dest: 'dist/php/concat.php'
}
},
htmlmin: {
dist: {
options: {
removeComments: true,
collapseWhitespace: true
},
tasks: ['clean:php'],
files: {
'index.php': 'dist/php/concat.php',
}
}
},
});
// Load NPM Tasks
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-htmlmin');
// Default
grunt.registerTask('default', ['concat','htmlmin']);
};
Result
It will not be fun, If I don't show you guys the result. Here is it.
if you want to create html file from php you can use PHP ob_start() function.
So you create PHP file php2html.php
php2html.php
<?php
ob_start();
include 'index.php';
file_put_contents('index.html', ob_get_clean());
then create exec task in GRUNT to call php2html.php script (read more about exec task https://github.com/jharding/grunt-exec
)
Gruntfile.js
module.exports = function(grunt) {
grunt.loadNpmTasks('grunt-exec');
grunt.initConfig({
exec: {
php2html: {
cmd: 'php php2html.php'
}
}
});
grunt.registerTask('default', ['exec:php2html']);
};
package.json
{
"name": "test",
"version": "0.0.0",
"description": "",
"main": "Gruntfile.js",
"dependencies": {
"grunt": "~0.4.5",
"grunt-exec": "~0.4.6"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "BSD-2-Clause"
}
and at the last minify created index.html
I'm trying Laravel Elixir and want to include bootstrap with includePaths but it does not work. Where am I going wrong?
var paths = {
'bootstrap': './vendor/bower_components/bootstrap-sass-official/assets/'
}
elixir(function(mix) {
mix.sass("style.scss", 'public/assets/css/', {includePaths: [paths.bootstrap + 'stylesheets/']})
});
I'm not sure if there is a reason that you want to do includePaths in your gulpfile, but for bootstrap you don't have to. The bootstrap include path is already configured out of the box in /node_modules/laravel-elixir/ingredients:
elixir.extend('sass', function(src, output, options) {
options = _.extend({
outputStyle: inProduction ? 'compressed' : 'nested',
includePaths: [elixir.config.bowerDir + "/bootstrap-sass-official/assets/stylesheets"]
}, options);
return compile({
compiler: 'Sass',
pluginName: 'sass',
pluginOptions: options,
src: src,
output: output,
search: '**/*.+(sass|scss)'
});
});
So all you should have to do is, in your gulpfile:
elixir(function(mix) {
mix.sass("style.scss");
});
And then in your style.scss:
#import "bootstrap";
I think you have to set your .bowerrc file to:
{
"directory": "vendor/bower_components"
}
but it looks like you have already done that.
I know this already has an accepted answer but I got something like this to work.
var paths = {
'bootstrap': '/bower_components/bootstrap-sass/assets/',
}
elixir(function (mix) {
mix.sass('app.scss', 'public/css', {
includePaths: [
__dirname + paths.bootstrap + 'stylesheets/'
]
});
mix.version("css/app.css");
});
Where bower_components is installed in the laravel root dir.
(From: https://laracasts.com/discuss/channels/requests/gulpfile-elixir-merge-scss-includepaths)
Another solution is using this line to compile sass or less files sitting in your vendor folder:
mix.less("../../../vendor/twbs/bootstrap/less/bootstrap.less");
Note: I used "composer require twbs/boostrap" to get the complete package. No bower needed.
Edit:
I output the compiled css file to the resource folder to combine it with other css files:
mix.less("../../../vendor/twbs/bootstrap/less/bootstrap.less", 'resources/css');
mix.styles([
"bootstrap.css"
], 'public/css/app.css');